Decompiled source of The Modded Company v1.8.0

BepInEx/core/0Harmony.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using HarmonyLib.Internal.Patching;
using HarmonyLib.Internal.RuntimeFixes;
using HarmonyLib.Internal.Util;
using HarmonyLib.Public.Patching;
using HarmonyLib.Tools;
using JetBrains.Annotations;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using MonoMod.Utils.Cil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("HarmonyTests")]
[assembly: InternalsVisibleTo("MonoMod.Utils.Cil.ILGeneratorProxy")]
[assembly: Guid("69aee16a-b6e7-4642-8081-3928b32455df")]
[assembly: AssemblyCompany("BepInEx")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © BepInEx 2022")]
[assembly: AssemblyDescription("A library for patching, replacing and decorating .NET and Mono methods during runtime powered by MonoMod.")]
[assembly: AssemblyFileVersion("2.9.0.0")]
[assembly: AssemblyInformationalVersion("2.9.0")]
[assembly: AssemblyProduct("HarmonyX")]
[assembly: AssemblyTitle("0Harmony")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.9.0.0")]
[module: UnverifiableCode]
namespace System
{
	internal struct ValueTuple<T1, T2>
	{
		public T1 Item1;

		public T2 Item2;

		public ValueTuple(T1 first, T2 second)
		{
			Item1 = first;
			Item2 = second;
		}
	}
	internal struct ValueTuple<T1, T2, T3>
	{
		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public ValueTuple(T1 first, T2 second, T3 third)
		{
			Item1 = first;
			Item2 = second;
			Item3 = third;
		}
	}
}
namespace JetBrains.Annotations
{
	[AttributeUsage(AttributeTargets.All)]
	internal sealed class UsedImplicitlyAttribute : Attribute
	{
		public ImplicitUseKindFlags UseKindFlags { get; }

		public ImplicitUseTargetFlags TargetFlags { get; }

		public UsedImplicitlyAttribute()
			: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
			: this(useKindFlags, ImplicitUseTargetFlags.Default)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
			: this(ImplicitUseKindFlags.Default, targetFlags)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
		{
			UseKindFlags = useKindFlags;
			TargetFlags = targetFlags;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter | AttributeTargets.GenericParameter)]
	internal sealed class MeansImplicitUseAttribute : Attribute
	{
		[UsedImplicitly]
		public ImplicitUseKindFlags UseKindFlags { get; }

		[UsedImplicitly]
		public ImplicitUseTargetFlags TargetFlags { get; }

		public MeansImplicitUseAttribute()
			: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
			: this(useKindFlags, ImplicitUseTargetFlags.Default)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
			: this(ImplicitUseKindFlags.Default, targetFlags)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
		{
			UseKindFlags = useKindFlags;
			TargetFlags = targetFlags;
		}
	}
	[Flags]
	internal enum ImplicitUseKindFlags
	{
		Default = 7,
		Access = 1,
		Assign = 2,
		InstantiatedWithFixedConstructorSignature = 4,
		InstantiatedNoFixedConstructorSignature = 8
	}
	[Flags]
	internal enum ImplicitUseTargetFlags
	{
		Default = 1,
		Itself = 1,
		Members = 2,
		WithInheritors = 4,
		WithMembers = 3
	}
}
namespace HarmonyLib
{
	public class DelegateTypeFactory
	{
		private class DelegateEntry
		{
			public CallingConvention? callingConvention;

			public Type delegateType;
		}

		private static int counter;

		private static readonly Dictionary<MethodInfo, List<DelegateEntry>> TypeCache = new Dictionary<MethodInfo, List<DelegateEntry>>();

		private static readonly MethodBase CallingConvAttr = AccessTools.Constructor(typeof(UnmanagedFunctionPointerAttribute), new Type[1] { typeof(CallingConvention) });

		public static readonly DelegateTypeFactory instance = new DelegateTypeFactory();

		public Type CreateDelegateType(Type returnType, Type[] argTypes)
		{
			return CreateDelegateType(returnType, argTypes, null);
		}

		public Type CreateDelegateType(Type returnType, Type[] argTypes, CallingConvention? convention)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_0127: 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_0134: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			counter++;
			AssemblyDefinition val = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition($"HarmonyDTFAssembly{counter}", new Version(1, 0)), $"HarmonyDTFModule{counter}", (ModuleKind)0);
			ModuleDefinition module = val.MainModule;
			TypeDefinition val2 = new TypeDefinition("", $"HarmonyDTFType{counter}", (TypeAttributes)257)
			{
				BaseType = module.ImportReference(typeof(MulticastDelegate))
			};
			module.Types.Add(val2);
			if (convention.HasValue)
			{
				CustomAttribute val3 = new CustomAttribute(module.ImportReference(CallingConvAttr));
				val3.ConstructorArguments.Add(new CustomAttributeArgument(module.ImportReference(typeof(CallingConvention)), (object)convention.Value));
				val2.CustomAttributes.Add(val3);
			}
			MethodDefinition val4 = new MethodDefinition(".ctor", (MethodAttributes)4230, module.ImportReference(typeof(void)))
			{
				ImplAttributes = (MethodImplAttributes)3
			};
			Extensions.AddRange<ParameterDefinition>(((MethodReference)val4).Parameters, (IEnumerable<ParameterDefinition>)(object)new ParameterDefinition[2]
			{
				new ParameterDefinition(module.ImportReference(typeof(object))),
				new ParameterDefinition(module.ImportReference(typeof(IntPtr)))
			});
			val2.Methods.Add(val4);
			MethodDefinition val5 = new MethodDefinition("Invoke", (MethodAttributes)198, module.ImportReference(returnType))
			{
				ImplAttributes = (MethodImplAttributes)3
			};
			Extensions.AddRange<ParameterDefinition>(((MethodReference)val5).Parameters, ((IEnumerable<Type>)argTypes).Select((Func<Type, ParameterDefinition>)((Type t) => new ParameterDefinition(module.ImportReference(t)))));
			val2.Methods.Add(val5);
			return ReflectionHelper.Load(val.MainModule).GetType($"HarmonyDTFType{counter}");
		}

		public Type CreateDelegateType(MethodInfo method)
		{
			return CreateDelegateType(method, null);
		}

		public Type CreateDelegateType(MethodInfo method, CallingConvention? convention)
		{
			DelegateEntry delegateEntry;
			if (TypeCache.TryGetValue(method, out var value) && (delegateEntry = value.FirstOrDefault((DelegateEntry e) => e.callingConvention == convention)) != null)
			{
				return delegateEntry.delegateType;
			}
			if (value == null)
			{
				value = (TypeCache[method] = new List<DelegateEntry>());
			}
			delegateEntry = new DelegateEntry
			{
				delegateType = CreateDelegateType(method.ReturnType, method.GetParameters().Types().ToArray(), convention),
				callingConvention = convention
			};
			value.Add(delegateEntry);
			return delegateEntry.delegateType;
		}
	}
	[Obsolete("Use AccessTools.FieldRefAccess<T, S> for fields and AccessTools.MethodDelegate<Func<T, S>> for property getters")]
	public delegate S GetterHandler<in T, out S>(T source);
	[Obsolete("Use AccessTools.FieldRefAccess<T, S> for fields and AccessTools.MethodDelegate<Action<T, S>> for property setters")]
	public delegate void SetterHandler<in T, in S>(T source, S value);
	public delegate T InstantiationHandler<out T>();
	public static class FastAccess
	{
		public static InstantiationHandler<T> CreateInstantiationHandler<T>()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);
			if ((object)constructor == null)
			{
				throw new ApplicationException($"The type {typeof(T)} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).");
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition("InstantiateObject_" + typeof(T).Name, typeof(T), (Type[])null);
			ILGenerator iLGenerator = val.GetILGenerator();
			iLGenerator.Emit(OpCodes.Newobj, constructor);
			iLGenerator.Emit(OpCodes.Ret);
			return (InstantiationHandler<T>)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(InstantiationHandler<T>));
		}

		[Obsolete("Use AccessTools.MethodDelegate<Func<T, S>>(PropertyInfo.GetGetMethod(true))")]
		public static GetterHandler<T, S> CreateGetterHandler<T, S>(PropertyInfo propertyInfo)
		{
			MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
			DynamicMethodDefinition obj = CreateGetDynamicMethod<T, S>(propertyInfo.DeclaringType);
			ILGenerator iLGenerator = obj.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Call, getMethod);
			iLGenerator.Emit(OpCodes.Ret);
			return (GetterHandler<T, S>)Extensions.CreateDelegate((MethodBase)obj.Generate(), typeof(GetterHandler<T, S>));
		}

		[Obsolete("Use AccessTools.FieldRefAccess<T, S>(fieldInfo)")]
		public static GetterHandler<T, S> CreateGetterHandler<T, S>(FieldInfo fieldInfo)
		{
			DynamicMethodDefinition obj = CreateGetDynamicMethod<T, S>(fieldInfo.DeclaringType);
			ILGenerator iLGenerator = obj.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (GetterHandler<T, S>)Extensions.CreateDelegate((MethodBase)obj.Generate(), typeof(GetterHandler<T, S>));
		}

		[Obsolete("Use AccessTools.FieldRefAccess<T, S>(name) for fields and AccessTools.MethodDelegate<Func<T, S>>(AccessTools.PropertyGetter(typeof(T), name)) for properties")]
		public static GetterHandler<T, S> CreateFieldGetter<T, S>(params string[] names)
		{
			foreach (string name in names)
			{
				FieldInfo field = typeof(T).GetField(name, AccessTools.all);
				if ((object)field != null)
				{
					return CreateGetterHandler<T, S>(field);
				}
				PropertyInfo property = typeof(T).GetProperty(name, AccessTools.all);
				if ((object)property != null)
				{
					return CreateGetterHandler<T, S>(property);
				}
			}
			return null;
		}

		[Obsolete("Use AccessTools.MethodDelegate<Action<T, S>>(PropertyInfo.GetSetMethod(true))")]
		public static SetterHandler<T, S> CreateSetterHandler<T, S>(PropertyInfo propertyInfo)
		{
			MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
			DynamicMethodDefinition obj = CreateSetDynamicMethod<T, S>(propertyInfo.DeclaringType);
			ILGenerator iLGenerator = obj.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			iLGenerator.Emit(OpCodes.Call, setMethod);
			iLGenerator.Emit(OpCodes.Ret);
			return (SetterHandler<T, S>)Extensions.CreateDelegate((MethodBase)obj.Generate(), typeof(SetterHandler<T, S>));
		}

		[Obsolete("Use AccessTools.FieldRefAccess<T, S>(fieldInfo)")]
		public static SetterHandler<T, S> CreateSetterHandler<T, S>(FieldInfo fieldInfo)
		{
			DynamicMethodDefinition obj = CreateSetDynamicMethod<T, S>(fieldInfo.DeclaringType);
			ILGenerator iLGenerator = obj.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (SetterHandler<T, S>)Extensions.CreateDelegate((MethodBase)obj.Generate(), typeof(SetterHandler<T, S>));
		}

		private static DynamicMethodDefinition CreateGetDynamicMethod<T, S>(Type type)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			return new DynamicMethodDefinition("DynamicGet_" + type.Name, typeof(S), new Type[1] { typeof(T) });
		}

		private static DynamicMethodDefinition CreateSetDynamicMethod<T, S>(Type type)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			return new DynamicMethodDefinition("DynamicSet_" + type.Name, typeof(void), new Type[2]
			{
				typeof(T),
				typeof(S)
			});
		}
	}
	public delegate object FastInvokeHandler(object target, params object[] parameters);
	public static class MethodInvoker
	{
		public static FastInvokeHandler GetHandler(MethodInfo methodInfo, bool directBoxValueAccess = false)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			DynamicMethodDefinition val = new DynamicMethodDefinition("FastInvoke_" + methodInfo.Name + "_" + (directBoxValueAccess ? "direct" : "indirect"), typeof(object), new Type[2]
			{
				typeof(object),
				typeof(object[])
			});
			ILGenerator iLGenerator = val.GetILGenerator();
			if (!methodInfo.IsStatic)
			{
				Emit(iLGenerator, OpCodes.Ldarg_0);
				EmitUnboxIfNeeded(iLGenerator, methodInfo.DeclaringType);
			}
			bool flag = true;
			ParameterInfo[] parameters = methodInfo.GetParameters();
			for (int i = 0; i < parameters.Length; i++)
			{
				Type type = parameters[i].ParameterType;
				bool isByRef = type.IsByRef;
				if (isByRef)
				{
					type = type.GetElementType();
				}
				bool isValueType = type.IsValueType;
				if (isByRef && isValueType && !directBoxValueAccess)
				{
					Emit(iLGenerator, OpCodes.Ldarg_1);
					EmitFastInt(iLGenerator, i);
				}
				Emit(iLGenerator, OpCodes.Ldarg_1);
				EmitFastInt(iLGenerator, i);
				if (isByRef && !isValueType)
				{
					Emit(iLGenerator, OpCodes.Ldelema, typeof(object));
					continue;
				}
				Emit(iLGenerator, OpCodes.Ldelem_Ref);
				if (!isValueType)
				{
					continue;
				}
				if (!isByRef || !directBoxValueAccess)
				{
					Emit(iLGenerator, OpCodes.Unbox_Any, type);
					if (isByRef)
					{
						Emit(iLGenerator, OpCodes.Box, type);
						Emit(iLGenerator, OpCodes.Dup);
						if (flag)
						{
							flag = false;
							iLGenerator.DeclareLocal(typeof(object), pinned: false);
						}
						Emit(iLGenerator, OpCodes.Stloc_0);
						Emit(iLGenerator, OpCodes.Stelem_Ref);
						Emit(iLGenerator, OpCodes.Ldloc_0);
						Emit(iLGenerator, OpCodes.Unbox, type);
					}
				}
				else
				{
					Emit(iLGenerator, OpCodes.Unbox, type);
				}
			}
			if (methodInfo.IsStatic)
			{
				EmitCall(iLGenerator, OpCodes.Call, methodInfo);
			}
			else
			{
				EmitCall(iLGenerator, OpCodes.Callvirt, methodInfo);
			}
			if ((object)methodInfo.ReturnType == typeof(void))
			{
				Emit(iLGenerator, OpCodes.Ldnull);
			}
			else
			{
				EmitBoxIfNeeded(iLGenerator, methodInfo.ReturnType);
			}
			Emit(iLGenerator, OpCodes.Ret);
			return (FastInvokeHandler)Extensions.CreateDelegate((MethodBase)val.Generate(), typeof(FastInvokeHandler));
		}

		internal static void Emit(ILGenerator il, OpCode opcode)
		{
			il.Emit(opcode);
		}

		internal static void Emit(ILGenerator il, OpCode opcode, Type type)
		{
			il.Emit(opcode, type);
		}

		internal static void EmitCall(ILGenerator il, OpCode opcode, MethodInfo methodInfo)
		{
			il.EmitCall(opcode, methodInfo, null);
		}

		private static void EmitUnboxIfNeeded(ILGenerator il, Type type)
		{
			if (type.IsValueType)
			{
				Emit(il, OpCodes.Unbox_Any, type);
			}
		}

		private static void EmitBoxIfNeeded(ILGenerator il, Type type)
		{
			if (type.IsValueType)
			{
				Emit(il, OpCodes.Box, type);
			}
		}

		internal static void EmitFastInt(ILGenerator il, int value)
		{
			switch (value)
			{
			case -1:
				il.Emit(OpCodes.Ldc_I4_M1);
				return;
			case 0:
				il.Emit(OpCodes.Ldc_I4_0);
				return;
			case 1:
				il.Emit(OpCodes.Ldc_I4_1);
				return;
			case 2:
				il.Emit(OpCodes.Ldc_I4_2);
				return;
			case 3:
				il.Emit(OpCodes.Ldc_I4_3);
				return;
			case 4:
				il.Emit(OpCodes.Ldc_I4_4);
				return;
			case 5:
				il.Emit(OpCodes.Ldc_I4_5);
				return;
			case 6:
				il.Emit(OpCodes.Ldc_I4_6);
				return;
			case 7:
				il.Emit(OpCodes.Ldc_I4_7);
				return;
			case 8:
				il.Emit(OpCodes.Ldc_I4_8);
				return;
			}
			if (value > -129 && value < 128)
			{
				il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
			}
			else
			{
				il.Emit(OpCodes.Ldc_I4, value);
			}
		}
	}
	internal class AccessCache
	{
		internal enum MemberType
		{
			Any,
			Static,
			Instance
		}

		private const BindingFlags BasicFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty;

		private static readonly Dictionary<MemberType, BindingFlags> declaredOnlyBindingFlags = new Dictionary<MemberType, BindingFlags>
		{
			{
				MemberType.Any,
				BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty
			},
			{
				MemberType.Instance,
				BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty
			},
			{
				MemberType.Static,
				BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty
			}
		};

		private readonly Dictionary<Type, Dictionary<string, FieldInfo>> declaredFields = new Dictionary<Type, Dictionary<string, FieldInfo>>();

		private readonly Dictionary<Type, Dictionary<string, PropertyInfo>> declaredProperties = new Dictionary<Type, Dictionary<string, PropertyInfo>>();

		private readonly Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>> declaredMethods = new Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>>();

		private readonly Dictionary<Type, Dictionary<string, FieldInfo>> inheritedFields = new Dictionary<Type, Dictionary<string, FieldInfo>>();

		private readonly Dictionary<Type, Dictionary<string, PropertyInfo>> inheritedProperties = new Dictionary<Type, Dictionary<string, PropertyInfo>>();

		private readonly Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>> inheritedMethods = new Dictionary<Type, Dictionary<string, Dictionary<int, MethodBase>>>();

		private static T Get<T>(Dictionary<Type, Dictionary<string, T>> dict, Type type, string name, Func<T> fetcher)
		{
			lock (dict)
			{
				if (!dict.TryGetValue(type, out var value))
				{
					value = (dict[type] = new Dictionary<string, T>());
				}
				if (!value.TryGetValue(name, out var value2))
				{
					value2 = (value[name] = fetcher());
				}
				return value2;
			}
		}

		private static T Get<T>(Dictionary<Type, Dictionary<string, Dictionary<int, T>>> dict, Type type, string name, Type[] arguments, Func<T> fetcher)
		{
			lock (dict)
			{
				if (!dict.TryGetValue(type, out var value))
				{
					value = (dict[type] = new Dictionary<string, Dictionary<int, T>>());
				}
				if (!value.TryGetValue(name, out var value2))
				{
					value2 = (value[name] = new Dictionary<int, T>());
				}
				int key = AccessTools.CombinedHashCode(arguments);
				if (!value2.TryGetValue(key, out var value3))
				{
					value3 = (value2[key] = fetcher());
				}
				return value3;
			}
		}

		internal FieldInfo GetFieldInfo(Type type, string name, MemberType memberType = MemberType.Any, bool declaredOnly = false)
		{
			FieldInfo fieldInfo = Get(declaredFields, type, name, () => type.GetField(name, declaredOnlyBindingFlags[memberType]));
			if ((object)fieldInfo == null && !declaredOnly)
			{
				fieldInfo = Get(inheritedFields, type, name, () => AccessTools.FindIncludingBaseTypes(type, (Type t) => t.GetField(name, AccessTools.all)));
			}
			return fieldInfo;
		}

		internal PropertyInfo GetPropertyInfo(Type type, string name, MemberType memberType = MemberType.Any, bool declaredOnly = false)
		{
			PropertyInfo propertyInfo = Get(declaredProperties, type, name, () => type.GetProperty(name, declaredOnlyBindingFlags[memberType]));
			if ((object)propertyInfo == null && !declaredOnly)
			{
				propertyInfo = Get(inheritedProperties, type, name, () => AccessTools.FindIncludingBaseTypes(type, (Type t) => t.GetProperty(name, AccessTools.all)));
			}
			return propertyInfo;
		}

		internal MethodBase GetMethodInfo(Type type, string name, Type[] arguments, MemberType memberType = MemberType.Any, bool declaredOnly = false)
		{
			MethodBase methodBase = Get(declaredMethods, type, name, arguments, () => type.GetMethod(name, declaredOnlyBindingFlags[memberType], null, arguments, null));
			if ((object)methodBase == null && !declaredOnly)
			{
				methodBase = Get(inheritedMethods, type, name, arguments, () => AccessTools.Method(type, name, arguments));
			}
			return methodBase;
		}
	}
	internal static class PatchArgumentExtensions
	{
		private static HarmonyArgument[] AllHarmonyArguments(object[] attributes)
		{
			return (from attr in attributes
				select (attr.GetType().Name != "HarmonyArgument") ? null : AccessTools.MakeDeepCopy<HarmonyArgument>(attr) into harg
				where harg != null
				select harg).ToArray();
		}

		private static HarmonyArgument GetArgumentAttribute(this ParameterInfo parameter)
		{
			return AllHarmonyArguments(parameter.GetCustomAttributes(inherit: false)).FirstOrDefault();
		}

		private static HarmonyArgument[] GetArgumentAttributes(this MethodInfo method)
		{
			if ((object)method == null || method is DynamicMethod)
			{
				return null;
			}
			return AllHarmonyArguments(method.GetCustomAttributes(inherit: false));
		}

		private static HarmonyArgument[] GetArgumentAttributes(this Type type)
		{
			return AllHarmonyArguments(type.GetCustomAttributes(inherit: false));
		}

		private static string GetOriginalArgumentName(this ParameterInfo parameter, string[] originalParameterNames)
		{
			HarmonyArgument argumentAttribute = parameter.GetArgumentAttribute();
			if (argumentAttribute == null)
			{
				return null;
			}
			if (!string.IsNullOrEmpty(argumentAttribute.OriginalName))
			{
				return argumentAttribute.OriginalName;
			}
			if (argumentAttribute.Index >= 0 && argumentAttribute.Index < originalParameterNames.Length)
			{
				return originalParameterNames[argumentAttribute.Index];
			}
			return null;
		}

		private static string GetOriginalArgumentName(HarmonyArgument[] attributes, string name, string[] originalParameterNames)
		{
			if (((attributes != null && attributes.Length != 0) ? 1 : 0) <= (false ? 1 : 0))
			{
				return null;
			}
			HarmonyArgument harmonyArgument = attributes.SingleOrDefault((HarmonyArgument p) => p.NewName == name);
			if (harmonyArgument == null)
			{
				return null;
			}
			if (!string.IsNullOrEmpty(harmonyArgument.OriginalName))
			{
				return harmonyArgument.OriginalName;
			}
			if (originalParameterNames != null && harmonyArgument.Index >= 0 && harmonyArgument.Index < originalParameterNames.Length)
			{
				return originalParameterNames[harmonyArgument.Index];
			}
			return null;
		}

		private static string GetOriginalArgumentName(this MethodInfo method, string[] originalParameterNames, string name)
		{
			string originalArgumentName = GetOriginalArgumentName(((object)method != null) ? method.GetArgumentAttributes() : null, name, originalParameterNames);
			if (originalArgumentName != null)
			{
				return originalArgumentName;
			}
			object attributes;
			if ((object)method == null)
			{
				attributes = null;
			}
			else
			{
				Type? declaringType = method.DeclaringType;
				attributes = (((object)declaringType != null) ? declaringType.GetArgumentAttributes() : null);
			}
			originalArgumentName = GetOriginalArgumentName((HarmonyArgument[])attributes, name, originalParameterNames);
			if (originalArgumentName != null)
			{
				return originalArgumentName;
			}
			return name;
		}

		internal static int GetArgumentIndex(this MethodInfo patch, string[] originalParameterNames, ParameterInfo patchParam)
		{
			if (patch is DynamicMethod)
			{
				return Array.IndexOf<string>(originalParameterNames, patchParam.Name);
			}
			string originalArgumentName = patchParam.GetOriginalArgumentName(originalParameterNames);
			if (originalArgumentName != null)
			{
				return Array.IndexOf(originalParameterNames, originalArgumentName);
			}
			originalArgumentName = patch.GetOriginalArgumentName(originalParameterNames, patchParam.Name);
			if (originalArgumentName != null)
			{
				return Array.IndexOf(originalParameterNames, originalArgumentName);
			}
			return -1;
		}
	}
	internal static class PatchFunctions
	{
		internal static List<MethodInfo> GetSortedPatchMethods(MethodBase original, Patch[] patches, bool debug)
		{
			return new PatchSorter(patches, debug).Sort(original);
		}

		internal static Patch[] GetSortedPatchMethodsAsPatches(MethodBase original, Patch[] patches, bool debug)
		{
			return new PatchSorter(patches, debug).SortAsPatches(original);
		}

		internal static MethodInfo UpdateWrapper(MethodBase original, PatchInfo patchInfo)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			MethodPatcher methodPatcher = original.GetMethodPatcher();
			DynamicMethodDefinition val = methodPatcher.PrepareOriginal();
			if (val != null)
			{
				ILContext ctx = new ILContext(val.Definition);
				HarmonyManipulator.Manipulate(original, patchInfo, ctx);
			}
			try
			{
				return methodPatcher.DetourTo((val != null) ? val.Generate() : null) as MethodInfo;
			}
			catch (Exception ex)
			{
				object body;
				if (val == null)
				{
					body = null;
				}
				else
				{
					MethodDefinition definition = val.Definition;
					body = ((definition != null) ? definition.Body : null);
				}
				throw HarmonyException.Create(ex, (MethodBody)body);
			}
		}

		internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase original, MethodInfo postTranspiler, MethodInfo postManipulator)
		{
			//IL_0140: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			if (standin == null)
			{
				throw new ArgumentNullException("standin");
			}
			if ((object)standin.method == null)
			{
				throw new ArgumentNullException("standin", "standin.method is NULL");
			}
			bool debug = standin.debug.GetValueOrDefault();
			List<MethodInfo> transpilers = new List<MethodInfo>();
			List<MethodInfo> ilmanipulators = new List<MethodInfo>();
			if (standin.reversePatchType == HarmonyReversePatchType.Snapshot)
			{
				Patches patchInfo = Harmony.GetPatchInfo(original);
				transpilers.AddRange(GetSortedPatchMethods(original, patchInfo.Transpilers.ToArray(), debug));
				ilmanipulators.AddRange(GetSortedPatchMethods(original, patchInfo.ILManipulators.ToArray(), debug));
			}
			if ((object)postTranspiler != null)
			{
				transpilers.Add(postTranspiler);
			}
			if ((object)postManipulator != null)
			{
				ilmanipulators.Add(postManipulator);
			}
			Logger.Log(Logger.LogChannel.Info, delegate
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("Reverse patching " + standin.method.FullDescription() + " with " + original.FullDescription());
				PrintInfo(stringBuilder, transpilers, "Transpiler");
				PrintInfo(stringBuilder, ilmanipulators, "Manipulators");
				return stringBuilder.ToString();
			}, debug);
			MethodBody patchBody = null;
			ILHook val = new ILHook((MethodBase)standin.method, (Manipulator)delegate(ILContext ctx)
			{
				//IL_00b8: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Expected O, but got Unknown
				//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
				if (original is MethodInfo methodInfo2)
				{
					patchBody = ctx.Body;
					MethodPatcher methodPatcher = methodInfo2.GetMethodPatcher();
					DynamicMethodDefinition val2 = methodPatcher.CopyOriginal();
					if (val2 == null)
					{
						throw new NullReferenceException("Cannot reverse patch " + methodInfo2.FullDescription() + ": method patcher (" + methodPatcher.GetType().FullDescription() + ") can't copy original method body");
					}
					ILManipulator iLManipulator = new ILManipulator(val2.Definition.Body, debug);
					ctx.Body.Variables.Clear();
					Enumerator<VariableDefinition> enumerator2 = iLManipulator.Body.Variables.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							VariableDefinition current2 = enumerator2.Current;
							ctx.Body.Variables.Add(new VariableDefinition(ctx.Module.ImportReference(((VariableReference)current2).VariableType)));
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
					foreach (MethodInfo item in transpilers)
					{
						iLManipulator.AddTranspiler(item);
					}
					iLManipulator.WriteTo(ctx.Body, standin.method);
					HarmonyManipulator.ApplyManipulators(ctx, original, ilmanipulators, null);
					Instruction val3 = null;
					foreach (Instruction item2 in ((IEnumerable<Instruction>)ctx.Instrs).Where((Instruction i) => i.OpCode == OpCodes.Ret))
					{
						if (val3 == null)
						{
							val3 = ctx.IL.Create(OpCodes.Ret);
						}
						item2.OpCode = OpCodes.Br;
						item2.Operand = val3;
					}
					if (val3 != null)
					{
						ctx.IL.Append(val3);
					}
					Logger.Log(Logger.LogChannel.IL, () => "Generated reverse patcher (" + ((MemberReference)ctx.Method).FullName + "):\n" + ctx.Body.ToILDasmString(), debug);
				}
			}, new ILHookConfig
			{
				ManualApply = true
			});
			try
			{
				val.Apply();
			}
			catch (Exception ex)
			{
				throw HarmonyException.Create(ex, patchBody);
			}
			MethodInfo methodInfo = val.GetCurrentTarget() as MethodInfo;
			PatchTools.RememberObject(standin.method, methodInfo);
			return methodInfo;
			static void PrintInfo(StringBuilder sb, ICollection<MethodInfo> methods, string name)
			{
				if (methods.Count <= 0)
				{
					return;
				}
				sb.AppendLine(name + ":");
				foreach (MethodInfo method in methods)
				{
					sb.AppendLine("  * " + method.FullDescription());
				}
			}
		}

		internal static IEnumerable<CodeInstruction> ApplyTranspilers(MethodBase methodBase, ILGenerator generator, int maxTranspilers = 0)
		{
			MethodPatcher methodPatcher = methodBase.GetMethodPatcher();
			DynamicMethodDefinition val = methodPatcher.CopyOriginal();
			if (val == null)
			{
				throw new NullReferenceException("Cannot reverse patch " + methodBase.FullDescription() + ": method patcher (" + methodPatcher.GetType().FullDescription() + ") can't copy original method body");
			}
			ILManipulator iLManipulator = new ILManipulator(val.Definition.Body, debug: false);
			PatchInfo patchInfo = methodBase.GetPatchInfo();
			if (patchInfo != null)
			{
				List<MethodInfo> sortedPatchMethods = GetSortedPatchMethods(methodBase, patchInfo.transpilers, debug: false);
				for (int i = 0; i < maxTranspilers && i < sortedPatchMethods.Count; i++)
				{
					iLManipulator.AddTranspiler(sortedPatchMethods[i]);
				}
			}
			return iLManipulator.GetInstructions(generator, methodBase);
		}

		internal static void UnpatchConditional(Func<Patch, bool> executionCondition)
		{
			foreach (MethodBase item in PatchProcessor.GetAllPatchedMethods().ToList())
			{
				bool num = item.HasMethodBody();
				Patches patchInfo2 = PatchProcessor.GetPatchInfo(item);
				PatchProcessor patchProcessor = new PatchProcessor(null, item);
				if (num)
				{
					patchInfo2.Postfixes.DoIf(executionCondition, delegate(Patch patchInfo)
					{
						patchProcessor.Unpatch(patchInfo.PatchMethod);
					});
					patchInfo2.Prefixes.DoIf(executionCondition, delegate(Patch patchInfo)
					{
						patchProcessor.Unpatch(patchInfo.PatchMethod);
					});
				}
				patchInfo2.ILManipulators.DoIf(executionCondition, delegate(Patch patchInfo)
				{
					patchProcessor.Unpatch(patchInfo.PatchMethod);
				});
				patchInfo2.Transpilers.DoIf(executionCondition, delegate(Patch patchInfo)
				{
					patchProcessor.Unpatch(patchInfo.PatchMethod);
				});
				if (num)
				{
					patchInfo2.Finalizers.DoIf(executionCondition, delegate(Patch patchInfo)
					{
						patchProcessor.Unpatch(patchInfo.PatchMethod);
					});
				}
			}
		}
	}
	internal class PatchJobs<T>
	{
		internal class Job
		{
			internal MethodBase original;

			internal T replacement;

			internal List<HarmonyMethod> prefixes = new List<HarmonyMethod>();

			internal List<HarmonyMethod> postfixes = new List<HarmonyMethod>();

			internal List<HarmonyMethod> transpilers = new List<HarmonyMethod>();

			internal List<HarmonyMethod> finalizers = new List<HarmonyMethod>();

			internal List<HarmonyMethod> ilmanipulators = new List<HarmonyMethod>();

			internal void AddPatch(AttributePatch patch)
			{
				HarmonyPatchType? type = patch.type;
				if (type.HasValue)
				{
					switch (type.GetValueOrDefault())
					{
					case HarmonyPatchType.Prefix:
						prefixes.Add(patch.info);
						break;
					case HarmonyPatchType.Postfix:
						postfixes.Add(patch.info);
						break;
					case HarmonyPatchType.Transpiler:
						transpilers.Add(patch.info);
						break;
					case HarmonyPatchType.Finalizer:
						finalizers.Add(patch.info);
						break;
					case HarmonyPatchType.ILManipulator:
						ilmanipulators.Add(patch.info);
						break;
					case HarmonyPatchType.ReversePatch:
						break;
					}
				}
			}
		}

		internal Dictionary<MethodBase, Job> state = new Dictionary<MethodBase, Job>();

		internal Job GetJob(MethodBase method)
		{
			if ((object)method == null)
			{
				return null;
			}
			if (!state.TryGetValue(method, out var value))
			{
				value = new Job
				{
					original = method
				};
				state[method] = value;
			}
			return value;
		}

		internal List<Job> GetJobs()
		{
			return state.Values.Where((Job job) => job.prefixes.Count + job.postfixes.Count + job.transpilers.Count + job.finalizers.Count + job.ilmanipulators.Count > 0).ToList();
		}

		internal List<T> GetReplacements()
		{
			return state.Values.Select((Job job) => job.replacement).ToList();
		}
	}
	internal class AttributePatch
	{
		private static readonly HarmonyPatchType[] allPatchTypes = new HarmonyPatchType[6]
		{
			HarmonyPatchType.Prefix,
			HarmonyPatchType.Postfix,
			HarmonyPatchType.Transpiler,
			HarmonyPatchType.Finalizer,
			HarmonyPatchType.ReversePatch,
			HarmonyPatchType.ILManipulator
		};

		internal HarmonyMethod info;

		internal HarmonyPatchType? type;

		private static readonly string harmonyAttributeName = typeof(HarmonyAttribute).FullName;

		internal static IEnumerable<AttributePatch> Create(MethodInfo patch, bool collectIncomplete = false)
		{
			if ((object)patch == null)
			{
				throw new NullReferenceException("Patch method cannot be null");
			}
			object[] customAttributes = patch.GetCustomAttributes(inherit: true);
			string name = patch.Name;
			HarmonyPatchType? type = GetPatchType(name, customAttributes);
			if (!type.HasValue)
			{
				return Enumerable.Empty<AttributePatch>();
			}
			if (type != HarmonyPatchType.ReversePatch && !patch.IsStatic)
			{
				throw new ArgumentException("Patch method " + patch.FullDescription() + " must be static");
			}
			List<HarmonyMethod> list = (from attr in customAttributes
				where attr.GetType().BaseType.FullName == harmonyAttributeName
				select AccessTools.Field(attr.GetType(), "info").GetValue(attr) into harmonyInfo
				select AccessTools.MakeDeepCopy<HarmonyMethod>(harmonyInfo)).ToList();
			List<HarmonyMethod> list2 = new List<HarmonyMethod>();
			ILookup<bool, HarmonyMethod> lookup = list.ToLookup((HarmonyMethod m) => IsComplete(m, collectIncomplete));
			List<HarmonyMethod> incomplete = lookup[false].ToList();
			HarmonyMethod info = HarmonyMethod.Merge(incomplete);
			List<HarmonyMethod> list3 = lookup[true].Where((HarmonyMethod m) => !Same(m, info)).ToList();
			if (list3.Count > 1)
			{
				list2.AddRange(list3.Select((HarmonyMethod m) => HarmonyMethod.Merge(incomplete.AddItem(m))));
			}
			else
			{
				list2.Add(HarmonyMethod.Merge(list));
			}
			foreach (HarmonyMethod item in list2)
			{
				item.method = patch;
			}
			return list2.Select((HarmonyMethod i) => new AttributePatch
			{
				info = i,
				type = type
			}).ToList();
			static bool IsComplete(HarmonyMethod m, bool collectIncomplete)
			{
				if (collectIncomplete || (object)m.GetDeclaringType() != null)
				{
					return m.methodName != null;
				}
				return false;
			}
			static bool Same(HarmonyMethod m1, HarmonyMethod m2)
			{
				if ((object)m1.GetDeclaringType() == m2.GetDeclaringType() && m1.methodName == m2.methodName)
				{
					return m1.GetArgumentList().SequenceEqual(m2.GetArgumentList());
				}
				return false;
			}
		}

		private static HarmonyPatchType? GetPatchType(string methodName, object[] allAttributes)
		{
			HashSet<string> hashSet = new HashSet<string>(from attr in allAttributes
				select attr.GetType().FullName into name
				where name.StartsWith("Harmony")
				select name);
			HarmonyPatchType? result = null;
			HarmonyPatchType[] array = allPatchTypes;
			for (int i = 0; i < array.Length; i++)
			{
				HarmonyPatchType value = array[i];
				string text = value.ToString();
				if (text == methodName || hashSet.Contains("HarmonyLib.Harmony" + text))
				{
					result = value;
					break;
				}
			}
			return result;
		}
	}
	internal class PatchSorter
	{
		private class PatchSortingWrapper : IComparable
		{
			internal readonly HashSet<PatchSortingWrapper> after;

			internal readonly HashSet<PatchSortingWrapper> before;

			internal readonly Patch innerPatch;

			internal PatchSortingWrapper(Patch patch)
			{
				innerPatch = patch;
				before = new HashSet<PatchSortingWrapper>();
				after = new HashSet<PatchSortingWrapper>();
			}

			public int CompareTo(object obj)
			{
				return PatchInfoSerialization.PriorityComparer((obj as PatchSortingWrapper)?.innerPatch, innerPatch.index, innerPatch.priority);
			}

			public override bool Equals(object obj)
			{
				if (obj is PatchSortingWrapper patchSortingWrapper)
				{
					return (object)innerPatch.PatchMethod == patchSortingWrapper.innerPatch.PatchMethod;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return innerPatch.PatchMethod.GetHashCode();
			}

			internal void AddBeforeDependency(IEnumerable<PatchSortingWrapper> dependencies)
			{
				foreach (PatchSortingWrapper dependency in dependencies)
				{
					before.Add(dependency);
					dependency.after.Add(this);
				}
			}

			internal void AddAfterDependency(IEnumerable<PatchSortingWrapper> dependencies)
			{
				foreach (PatchSortingWrapper dependency in dependencies)
				{
					after.Add(dependency);
					dependency.before.Add(this);
				}
			}

			internal void RemoveAfterDependency(PatchSortingWrapper afterNode)
			{
				after.Remove(afterNode);
				afterNode.before.Remove(this);
			}

			internal void RemoveBeforeDependency(PatchSortingWrapper beforeNode)
			{
				before.Remove(beforeNode);
				beforeNode.after.Remove(this);
			}
		}

		internal class PatchDetailedComparer : IEqualityComparer<Patch>
		{
			public bool Equals(Patch x, Patch y)
			{
				if (y != null && x != null && x.owner == y.owner && (object)x.PatchMethod == y.PatchMethod && x.index == y.index && x.priority == y.priority && x.before.Length == y.before.Length && x.after.Length == y.after.Length && x.before.All(((IEnumerable<string>)y.before).Contains<string>))
				{
					return x.after.All(((IEnumerable<string>)y.after).Contains<string>);
				}
				return false;
			}

			public int GetHashCode(Patch obj)
			{
				return obj.GetHashCode();
			}
		}

		private List<PatchSortingWrapper> patches;

		private HashSet<PatchSortingWrapper> handledPatches;

		private List<PatchSortingWrapper> result;

		private List<PatchSortingWrapper> waitingList;

		internal Patch[] sortedPatchArray;

		private readonly bool debug;

		internal PatchSorter(Patch[] patches, bool debug = false)
		{
			this.patches = patches.Select((Patch x) => new PatchSortingWrapper(x)).ToList();
			this.debug = debug;
			foreach (PatchSortingWrapper node in this.patches)
			{
				node.AddBeforeDependency(this.patches.Where((PatchSortingWrapper x) => node.innerPatch.before.Contains(x.innerPatch.owner)));
				node.AddAfterDependency(this.patches.Where((PatchSortingWrapper x) => node.innerPatch.after.Contains(x.innerPatch.owner)));
			}
			this.patches.Sort();
		}

		internal List<MethodInfo> Sort(MethodBase original)
		{
			return (from x in SortAsPatches(original)
				select x.GetMethod(original)).ToList();
		}

		internal Patch[] SortAsPatches(MethodBase original)
		{
			if (sortedPatchArray != null)
			{
				return sortedPatchArray;
			}
			handledPatches = new HashSet<PatchSortingWrapper>();
			waitingList = new List<PatchSortingWrapper>();
			result = new List<PatchSortingWrapper>(patches.Count);
			Queue<PatchSortingWrapper> queue = new Queue<PatchSortingWrapper>(patches);
			while (queue.Count != 0)
			{
				foreach (PatchSortingWrapper item in queue)
				{
					if (item.after.All((PatchSortingWrapper x) => handledPatches.Contains(x)))
					{
						AddNodeToResult(item);
						if (item.before.Count != 0)
						{
							ProcessWaitingList();
						}
					}
					else
					{
						waitingList.Add(item);
					}
				}
				CullDependency();
				queue = new Queue<PatchSortingWrapper>(waitingList);
				waitingList.Clear();
			}
			sortedPatchArray = result.Select((PatchSortingWrapper x) => x.innerPatch).ToArray();
			handledPatches = null;
			waitingList = null;
			patches = null;
			return sortedPatchArray;
		}

		internal bool ComparePatchLists(Patch[] patches)
		{
			if (sortedPatchArray == null)
			{
				Sort(null);
			}
			if (patches != null && sortedPatchArray.Length == patches.Length)
			{
				return sortedPatchArray.All((Patch x) => patches.Contains(x, new PatchDetailedComparer()));
			}
			return false;
		}

		private void CullDependency()
		{
			for (int i = waitingList.Count - 1; i >= 0; i--)
			{
				foreach (PatchSortingWrapper afterNode in waitingList[i].after)
				{
					if (!handledPatches.Contains(afterNode))
					{
						waitingList[i].RemoveAfterDependency(afterNode);
						Logger.Log(Logger.LogChannel.Debug, delegate
						{
							string text = afterNode.innerPatch.PatchMethod.FullDescription();
							string text2 = waitingList[i].innerPatch.PatchMethod.FullDescription();
							return "Breaking dependence between " + text + " and " + text2;
						}, debug);
						return;
					}
				}
			}
		}

		private void ProcessWaitingList()
		{
			int num = waitingList.Count;
			int num2 = 0;
			while (num2 < num)
			{
				PatchSortingWrapper patchSortingWrapper = waitingList[num2];
				if (patchSortingWrapper.after.All(handledPatches.Contains))
				{
					waitingList.Remove(patchSortingWrapper);
					AddNodeToResult(patchSortingWrapper);
					num--;
					num2 = 0;
				}
				else
				{
					num2++;
				}
			}
		}

		private void AddNodeToResult(PatchSortingWrapper node)
		{
			result.Add(node);
			handledPatches.Add(node);
		}
	}
	internal static class PatchTools
	{
		[ThreadStatic]
		private static Dictionary<object, object> objectReferences;

		internal static void RememberObject(object key, object value)
		{
			if (objectReferences == null)
			{
				objectReferences = new Dictionary<object, object>();
			}
			objectReferences[key] = value;
		}

		internal static MethodInfo GetPatchMethod(Type patchType, string attributeName)
		{
			MethodInfo methodInfo = patchType.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().FullName == attributeName));
			if ((object)methodInfo == null)
			{
				string name = attributeName.Replace("HarmonyLib.Harmony", "");
				methodInfo = patchType.GetMethod(name, AccessTools.all);
			}
			return methodInfo;
		}

		internal static AssemblyBuilder DefineDynamicAssembly(string name)
		{
			AssemblyName assemblyName = new AssemblyName(name);
			return AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
		}

		internal static List<AttributePatch> GetPatchMethods(Type type, bool collectIncomplete = false)
		{
			return (from attributePatch in AccessTools.GetDeclaredMethods(type).SelectMany((MethodInfo m) => AttributePatch.Create(m, collectIncomplete))
				where attributePatch != null
				select attributePatch).ToList();
		}

		internal static MethodBase GetOriginalMethod(this HarmonyMethod attr)
		{
			try
			{
				MethodType? methodType = attr.methodType;
				if (methodType.HasValue)
				{
					switch (methodType.GetValueOrDefault())
					{
					case MethodType.Normal:
						if (attr.methodName == null)
						{
							return null;
						}
						return AccessTools.DeclaredMethod(attr.GetDeclaringType(), attr.methodName, attr.argumentTypes);
					case MethodType.Getter:
						if (attr.methodName == null)
						{
							return null;
						}
						return AccessTools.DeclaredProperty(attr.GetDeclaringType(), attr.methodName).GetGetMethod(nonPublic: true);
					case MethodType.Setter:
						if (attr.methodName == null)
						{
							return null;
						}
						return AccessTools.DeclaredProperty(attr.GetDeclaringType(), attr.methodName).GetSetMethod(nonPublic: true);
					case MethodType.Constructor:
						return AccessTools.DeclaredConstructor(attr.GetDeclaringType(), attr.argumentTypes);
					case MethodType.StaticConstructor:
						return AccessTools.GetDeclaredConstructors(attr.GetDeclaringType()).FirstOrDefault((ConstructorInfo c) => c.IsStatic);
					case MethodType.Enumerator:
						if (attr.methodName == null)
						{
							return null;
						}
						return AccessTools.EnumeratorMoveNext(AccessTools.DeclaredMethod(attr.GetDeclaringType(), attr.methodName, attr.argumentTypes));
					}
				}
			}
			catch (AmbiguousMatchException ex)
			{
				throw new HarmonyException("Ambiguous match for HarmonyMethod[" + attr.Description() + "]", ex.InnerException ?? ex);
			}
			return null;
		}
	}
	public enum MethodType
	{
		Normal,
		Getter,
		Setter,
		Constructor,
		StaticConstructor,
		Enumerator
	}
	public enum ArgumentType
	{
		Normal,
		Ref,
		Out,
		Pointer
	}
	public enum HarmonyPatchType
	{
		All,
		Prefix,
		Postfix,
		Transpiler,
		Finalizer,
		ReversePatch,
		ILManipulator
	}
	public enum HarmonyReversePatchType
	{
		Original,
		Snapshot
	}
	public enum MethodDispatchType
	{
		VirtualCall,
		Call
	}
	[MeansImplicitUse]
	public class HarmonyAttribute : Attribute
	{
		public HarmonyMethod info = new HarmonyMethod();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Delegate, AllowMultiple = true)]
	public class HarmonyPatch : HarmonyAttribute
	{
		public HarmonyPatch()
		{
		}

		public HarmonyPatch(Type declaringType)
		{
			info.declaringType = declaringType;
		}

		public HarmonyPatch(Type declaringType, Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, string methodName)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
		}

		public HarmonyPatch(Type declaringType, string methodName, params Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(string assemblyQualifiedDeclaringType, string methodName)
		{
			info.assemblyQualifiedDeclaringTypeName = assemblyQualifiedDeclaringType;
			info.methodName = methodName;
		}

		public HarmonyPatch(string assemblyQualifiedDeclaringType, string methodName, MethodType methodType, Type[] argumentTypes = null, ArgumentType[] argumentVariations = null)
		{
			info.assemblyQualifiedDeclaringTypeName = assemblyQualifiedDeclaringType;
			info.methodName = methodName;
			info.methodType = methodType;
			if (argumentTypes != null)
			{
				ParseSpecialArguments(argumentTypes, argumentVariations);
			}
		}

		public HarmonyPatch(Type declaringType, MethodType methodType)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
		}

		public HarmonyPatch(Type declaringType, MethodType methodType, params Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(Type declaringType, string methodName, MethodType methodType)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			info.methodType = methodType;
		}

		public HarmonyPatch(string methodName)
		{
			info.methodName = methodName;
		}

		public HarmonyPatch(string methodName, params Type[] argumentTypes)
		{
			info.methodName = methodName;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.methodName = methodName;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(string methodName, MethodType methodType)
		{
			info.methodName = methodName;
			info.methodType = methodType;
		}

		public HarmonyPatch(MethodType methodType)
		{
			info.methodType = methodType;
		}

		public HarmonyPatch(MethodType methodType, params Type[] argumentTypes)
		{
			info.methodType = methodType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.methodType = methodType;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(Type[] argumentTypes)
		{
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		private void ParseSpecialArguments(Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			if (argumentVariations == null || argumentVariations.Length == 0)
			{
				info.argumentTypes = argumentTypes;
				return;
			}
			if (argumentTypes.Length < argumentVariations.Length)
			{
				throw new ArgumentException("argumentVariations contains more elements than argumentTypes", "argumentVariations");
			}
			List<Type> list = new List<Type>();
			for (int i = 0; i < argumentTypes.Length; i++)
			{
				Type type = argumentTypes[i];
				switch (argumentVariations[i])
				{
				case ArgumentType.Ref:
				case ArgumentType.Out:
					type = type.MakeByRefType();
					break;
				case ArgumentType.Pointer:
					type = type.MakePointerType();
					break;
				}
				list.Add(type);
			}
			info.argumentTypes = list.ToArray();
		}
	}
	[AttributeUsage(AttributeTargets.Delegate, AllowMultiple = true)]
	public class HarmonyDelegate : HarmonyPatch
	{
		public HarmonyDelegate(Type declaringType)
			: base(declaringType)
		{
		}

		public HarmonyDelegate(Type declaringType, Type[] argumentTypes)
			: base(declaringType, argumentTypes)
		{
		}

		public HarmonyDelegate(Type declaringType, string methodName)
			: base(declaringType, methodName)
		{
		}

		public HarmonyDelegate(Type declaringType, string methodName, params Type[] argumentTypes)
			: base(declaringType, methodName, argumentTypes)
		{
		}

		public HarmonyDelegate(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
			: base(declaringType, methodName, argumentTypes, argumentVariations)
		{
		}

		public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType)
			: base(declaringType, MethodType.Normal)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType, params Type[] argumentTypes)
			: base(declaringType, MethodType.Normal, argumentTypes)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(Type declaringType, MethodDispatchType methodDispatchType, Type[] argumentTypes, ArgumentType[] argumentVariations)
			: base(declaringType, MethodType.Normal, argumentTypes, argumentVariations)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(Type declaringType, string methodName, MethodDispatchType methodDispatchType)
			: base(declaringType, methodName, MethodType.Normal)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(string methodName)
			: base(methodName)
		{
		}

		public HarmonyDelegate(string methodName, params Type[] argumentTypes)
			: base(methodName, argumentTypes)
		{
		}

		public HarmonyDelegate(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
			: base(methodName, argumentTypes, argumentVariations)
		{
		}

		public HarmonyDelegate(string methodName, MethodDispatchType methodDispatchType)
			: base(methodName, MethodType.Normal)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(MethodDispatchType methodDispatchType)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(MethodDispatchType methodDispatchType, params Type[] argumentTypes)
			: base(MethodType.Normal, argumentTypes)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(MethodDispatchType methodDispatchType, Type[] argumentTypes, ArgumentType[] argumentVariations)
			: base(MethodType.Normal, argumentTypes, argumentVariations)
		{
			info.nonVirtualDelegate = methodDispatchType == MethodDispatchType.Call;
		}

		public HarmonyDelegate(Type[] argumentTypes)
			: base(argumentTypes)
		{
		}

		public HarmonyDelegate(Type[] argumentTypes, ArgumentType[] argumentVariations)
			: base(argumentTypes, argumentVariations)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
	public class HarmonyReversePatch : HarmonyAttribute
	{
		public HarmonyReversePatch(HarmonyReversePatchType type = HarmonyReversePatchType.Original)
		{
			info.reversePatchType = type;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class HarmonyPatchAll : HarmonyAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyPriority : HarmonyAttribute
	{
		public HarmonyPriority(int priority)
		{
			info.priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyBefore : HarmonyAttribute
	{
		public HarmonyBefore(params string[] before)
		{
			info.before = before;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyAfter : HarmonyAttribute
	{
		public HarmonyAfter(params string[] after)
		{
			info.after = after;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyDebug : HarmonyAttribute
	{
		public HarmonyDebug()
		{
			info.debug = true;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyEmitIL : HarmonyAttribute
	{
		public HarmonyEmitIL()
		{
			info.debugEmitPath = "./";
		}

		public HarmonyEmitIL(string dir)
		{
			info.debugEmitPath = dir;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyWrapSafe : HarmonyAttribute
	{
		public HarmonyWrapSafe()
		{
			info.wrapTryCatch = true;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPrepare : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyCleanup : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTargetMethod : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTargetMethods : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPrefix : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPostfix : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTranspiler : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyILManipulator : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyFinalizer : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = true)]
	public class HarmonyArgument : Attribute
	{
		public string OriginalName { get; private set; }

		public int Index { get; private set; }

		public string NewName { get; private set; }

		public HarmonyArgument(string originalName)
			: this(originalName, null)
		{
		}

		public HarmonyArgument(int index)
			: this(index, null)
		{
		}

		public HarmonyArgument(string originalName, string newName)
		{
			OriginalName = originalName;
			Index = -1;
			NewName = newName;
		}

		public HarmonyArgument(int index, string name)
		{
			OriginalName = null;
			Index = index;
			NewName = name;
		}
	}
	public class CodeInstruction
	{
		public OpCode opcode;

		public object operand;

		public List<Label> labels = new List<Label>();

		public List<ExceptionBlock> blocks = new List<ExceptionBlock>();

		internal CodeInstruction()
		{
		}

		public CodeInstruction(OpCode opcode, object operand = null)
		{
			this.opcode = opcode;
			this.operand = operand;
		}

		public CodeInstruction(CodeInstruction instruction)
		{
			opcode = instruction.opcode;
			operand = instruction.operand;
			labels = instruction.labels.ToList();
			blocks = instruction.blocks.ToList();
		}

		public CodeInstruction Clone()
		{
			return new CodeInstruction(this)
			{
				labels = new List<Label>(),
				blocks = new List<ExceptionBlock>()
			};
		}

		public CodeInstruction Clone(OpCode opcode)
		{
			CodeInstruction codeInstruction = Clone();
			codeInstruction.opcode = opcode;
			return codeInstruction;
		}

		public CodeInstruction Clone(object operand)
		{
			CodeInstruction codeInstruction = Clone();
			codeInstruction.operand = operand;
			return codeInstruction;
		}

		public static CodeInstruction Call(Type type, string name, Type[] parameters = null, Type[] generics = null)
		{
			MethodInfo methodInfo = AccessTools.Method(type, name, parameters, generics);
			if ((object)methodInfo == null)
			{
				throw new ArgumentException($"No method found for type={type}, name={name}, parameters={parameters.Description()}, generics={generics.Description()}");
			}
			return new CodeInstruction(OpCodes.Call, methodInfo);
		}

		public static CodeInstruction Call(string typeColonMethodname, Type[] parameters = null, Type[] generics = null)
		{
			MethodInfo methodInfo = AccessTools.Method(typeColonMethodname, parameters, generics);
			if ((object)methodInfo == null)
			{
				throw new ArgumentException("No method found for " + typeColonMethodname + ", parameters=" + parameters.Description() + ", generics=" + generics.Description());
			}
			return new CodeInstruction(OpCodes.Call, methodInfo);
		}

		public static CodeInstruction Call(Expression<Action> expression)
		{
			return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression));
		}

		public static CodeInstruction Call<T>(Expression<Action<T>> expression)
		{
			return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression));
		}

		public static CodeInstruction Call<T, TResult>(Expression<Func<T, TResult>> expression)
		{
			return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression));
		}

		public static CodeInstruction Call(LambdaExpression expression)
		{
			return new CodeInstruction(OpCodes.Call, SymbolExtensions.GetMethodInfo(expression));
		}

		public static CodeInstruction CallClosure<T>(T closure) where T : Delegate
		{
			return Transpilers.EmitDelegate(closure);
		}

		public static CodeInstruction LoadField(Type type, string name, bool useAddress = false)
		{
			FieldInfo fieldInfo = AccessTools.Field(type, name);
			if ((object)fieldInfo == null)
			{
				throw new ArgumentException($"No field found for {type} and {name}");
			}
			return new CodeInstruction((!useAddress) ? (fieldInfo.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld) : (fieldInfo.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda), fieldInfo);
		}

		public static CodeInstruction StoreField(Type type, string name)
		{
			FieldInfo fieldInfo = AccessTools.Field(type, name);
			if ((object)fieldInfo == null)
			{
				throw new ArgumentException($"No field found for {type} and {name}");
			}
			return new CodeInstruction(fieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fieldInfo);
		}

		public override string ToString()
		{
			List<string> list = new List<string>();
			foreach (Label label in labels)
			{
				list.Add($"Label{label.GetHashCode()}");
			}
			foreach (ExceptionBlock block in blocks)
			{
				list.Add("EX_" + block.blockType.ToString().Replace("Block", ""));
			}
			string text = ((list.Count > 0) ? (" [" + string.Join(", ", list.ToArray()) + "]") : "");
			string text2 = FormatArgument(operand);
			if (text2.Length > 0)
			{
				text2 = " " + text2;
			}
			OpCode opCode = opcode;
			return opCode.ToString() + text2 + text;
		}

		internal static string FormatArgument(object argument, string extra = null)
		{
			if (argument == null)
			{
				return "NULL";
			}
			Type type = argument.GetType();
			if (argument is MethodBase member)
			{
				return member.FullDescription() + ((extra != null) ? (" " + extra) : "");
			}
			if (argument is FieldInfo fieldInfo)
			{
				return fieldInfo.FieldType.FullDescription() + " " + fieldInfo.DeclaringType.FullDescription() + "::" + fieldInfo.Name;
			}
			if ((object)type == typeof(Label))
			{
				return $"Label{((Label)argument).GetHashCode()}";
			}
			if ((object)type == typeof(Label[]))
			{
				return "Labels" + string.Join(",", ((Label[])argument).Select((Label l) => l.GetHashCode().ToString()).ToArray());
			}
			if ((object)type == typeof(LocalBuilder))
			{
				return $"{((LocalBuilder)argument).LocalIndex} ({((LocalBuilder)argument).LocalType})";
			}
			if ((object)type == typeof(string))
			{
				return argument.ToString().ToLiteral();
			}
			return argument.ToString().Trim();
		}
	}
	public enum ExceptionBlockType
	{
		BeginExceptionBlock,
		BeginCatchBlock,
		BeginExceptFilterBlock,
		BeginFaultBlock,
		BeginFinallyBlock,
		EndExceptionBlock
	}
	public class ExceptionBlock
	{
		public ExceptionBlockType blockType;

		public Type catchType;

		public ExceptionBlock(ExceptionBlockType blockType, Type catchType = null)
		{
			this.blockType = blockType;
			this.catchType = catchType ?? typeof(object);
		}
	}
	public class InvalidHarmonyPatchArgumentException : Exception
	{
		public MethodBase Original { get; }

		public MethodInfo Patch { get; }

		public override string Message => "(" + Patch.FullDescription() + "): " + base.Message;

		public InvalidHarmonyPatchArgumentException(string message, MethodBase original, MethodInfo patch)
			: base(message)
		{
			Original = original;
			Patch = patch;
		}
	}
	public class MemberNotFoundException : Exception
	{
		public MemberNotFoundException(string message)
			: base(message)
		{
		}
	}
	public class Harmony : IDisposable
	{
		[Obsolete("Use HarmonyFileLog.Enabled instead")]
		public static bool DEBUG;

		public string Id { get; }

		static Harmony()
		{
			StackTraceFixes.Install();
		}

		public Harmony(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("id cannot be null or empty");
			}
			try
			{
				string environmentVariable = Environment.GetEnvironmentVariable("HARMONY_DEBUG");
				if (environmentVariable != null && environmentVariable.Length > 0)
				{
					environmentVariable = environmentVariable.Trim();
					DEBUG = environmentVariable == "1" || bool.Parse(environmentVariable);
				}
			}
			catch
			{
			}
			if (DEBUG)
			{
				HarmonyFileLog.Enabled = true;
			}
			MethodBase callingMethod = (Logger.IsEnabledFor(Logger.LogChannel.Info) ? AccessTools.GetOutsideCaller() : null);
			Logger.Log(Logger.LogChannel.Info, delegate
			{
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				StringBuilder stringBuilder = new StringBuilder();
				Assembly assembly = typeof(Harmony).Assembly;
				Version version = assembly.GetName().Version;
				string text = assembly.Location;
				string text2 = Environment.Version.ToString();
				string text3 = Environment.OSVersion.Platform.ToString();
				if (string.IsNullOrEmpty(text))
				{
					text = new Uri(assembly.CodeBase).LocalPath;
				}
				int size = IntPtr.Size;
				Platform current = PlatformHelper.Current;
				stringBuilder.AppendLine($"### Harmony id={id}, version={version}, location={text}, env/clr={text2}, platform={text3}, ptrsize:runtime/env={size}/{current}");
				if ((object)callingMethod?.DeclaringType != null)
				{
					Assembly assembly2 = callingMethod.DeclaringType.Assembly;
					text = assembly2.Location;
					if (string.IsNullOrEmpty(text))
					{
						text = new Uri(assembly2.CodeBase).LocalPath;
					}
					stringBuilder.AppendLine("### Started from " + callingMethod.FullDescription() + ", location " + text);
					stringBuilder.Append($"### At {DateTime.Now:yyyy-MM-dd hh.mm.ss}");
				}
				return stringBuilder.ToString();
			});
			Id = id;
		}

		public void PatchAll()
		{
			Assembly assembly = new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly;
			PatchAll(assembly);
		}

		public PatchProcessor CreateProcessor(MethodBase original)
		{
			return new PatchProcessor(this, original);
		}

		public PatchClassProcessor CreateClassProcessor(Type type)
		{
			return new PatchClassProcessor(this, type);
		}

		public PatchClassProcessor CreateClassProcessor(Type type, bool allowUnannotatedType)
		{
			return new PatchClassProcessor(this, type, allowUnannotatedType);
		}

		public ReversePatcher CreateReversePatcher(MethodBase original, HarmonyMethod standin)
		{
			return new ReversePatcher(this, original, standin);
		}

		public void PatchAll(Assembly assembly)
		{
			AccessTools.GetTypesFromAssembly(assembly).Do(delegate(Type type)
			{
				CreateClassProcessor(type).Patch();
			});
		}

		public void PatchAll(Type type)
		{
			CreateClassProcessor(type, allowUnannotatedType: true).Patch();
		}

		public MethodInfo Patch(MethodBase original, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null, HarmonyMethod ilmanipulator = null)
		{
			PatchProcessor patchProcessor = CreateProcessor(original);
			patchProcessor.AddPrefix(prefix);
			patchProcessor.AddPostfix(postfix);
			patchProcessor.AddTranspiler(transpiler);
			patchProcessor.AddFinalizer(finalizer);
			patchProcessor.AddILManipulator(ilmanipulator);
			return patchProcessor.Patch();
		}

		[Obsolete("Use newer Patch() instead", true)]
		public MethodInfo Patch(MethodBase original, HarmonyMethod prefix, HarmonyMethod postfix, HarmonyMethod transpiler, HarmonyMethod finalizer)
		{
			return Patch(original, prefix, postfix, transpiler, finalizer, null);
		}

		public static MethodInfo ReversePatch(MethodBase original, HarmonyMethod standin, MethodInfo transpiler = null, MethodInfo ilmanipulator = null)
		{
			return PatchFunctions.ReversePatch(standin, original, transpiler, ilmanipulator);
		}

		[Obsolete("Use newer ReversePatch() instead", true)]
		public static MethodInfo ReversePatch(MethodBase original, HarmonyMethod standin, MethodInfo transpiler)
		{
			return PatchFunctions.ReversePatch(standin, original, transpiler, null);
		}

		public static void UnpatchID(string harmonyID)
		{
			if (string.IsNullOrEmpty(harmonyID))
			{
				throw new ArgumentNullException("harmonyID", "UnpatchID was called with a null or empty harmonyID.");
			}
			PatchFunctions.UnpatchConditional((Patch patchInfo) => patchInfo.owner == harmonyID);
		}

		void IDisposable.Dispose()
		{
			UnpatchSelf();
		}

		public void UnpatchSelf()
		{
			UnpatchID(Id);
		}

		public static void UnpatchAll()
		{
			Logger.Log(Logger.LogChannel.Warn, () => "UnpatchAll has been called - This will remove ALL HARMONY PATCHES.");
			PatchFunctions.UnpatchConditional((Patch _) => true);
		}

		[Obsolete("Use UnpatchSelf() to unpatch the current instance. The functionality to unpatch either other ids or EVERYTHING has been moved the static methods UnpatchID() and UnpatchAll() respectively", true)]
		public void UnpatchAll(string harmonyID = null)
		{
			if (harmonyID == null)
			{
				if (HarmonyGlobalSettings.DisallowLegacyGlobalUnpatchAll)
				{
					Logger.Log(Logger.LogChannel.Warn, () => "Legacy UnpatchAll has been called AND DisallowLegacyGlobalUnpatchAll=true. Skipping execution of UnpatchAll");
				}
				else
				{
					UnpatchAll();
				}
			}
			else if (harmonyID.Length == 0)
			{
				Logger.Log(Logger.LogChannel.Warn, () => "Legacy UnpatchAll was called with harmonyID=\"\" which is an invalid id. Skipping execution of UnpatchAll");
			}
			else
			{
				UnpatchID(harmonyID);
			}
		}

		public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyID = null)
		{
			CreateProcessor(original).Unpatch(type, harmonyID);
		}

		public void Unpatch(MethodBase original, MethodInfo patch)
		{
			CreateProcessor(original).Unpatch(patch);
		}

		public static bool HasAnyPatches(string harmonyID)
		{
			return (from original in GetAllPatchedMethods()
				select GetPatchInfo(original)).Any((Patches info) => info.Owners.Contains(harmonyID));
		}

		public static Patches GetPatchInfo(MethodBase method)
		{
			return PatchProcessor.GetPatchInfo(method);
		}

		public IEnumerable<MethodBase> GetPatchedMethods()
		{
			return from original in GetAllPatchedMethods()
				where GetPatchInfo(original).Owners.Contains(Id)
				select original;
		}

		public static IEnumerable<MethodBase> GetAllPatchedMethods()
		{
			return PatchProcessor.GetAllPatchedMethods();
		}

		public static MethodBase GetOriginalMethod(MethodInfo replacement)
		{
			if ((object)replacement == null)
			{
				throw new ArgumentNullException("replacement");
			}
			return PatchManager.GetOriginal(replacement);
		}

		public static MethodBase GetMethodFromStackframe(StackFrame frame)
		{
			if (frame == null)
			{
				throw new ArgumentNullException("frame");
			}
			return PatchManager.FindReplacement(frame) ?? frame.GetMethod();
		}

		public static Dictionary<string, Version> VersionInfo(out Version currentVersion)
		{
			return PatchProcessor.VersionInfo(out currentVersion);
		}

		public static Harmony CreateAndPatchAll(Type type, string harmonyInstanceId = null)
		{
			Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Guid.NewGuid()}");
			harmony.PatchAll(type);
			return harmony;
		}

		public static Harmony CreateAndPatchAll(Assembly assembly, string harmonyInstanceId = null)
		{
			Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Guid.NewGuid()}");
			harmony.PatchAll(assembly);
			return harmony;
		}
	}
	[Serializable]
	public class HarmonyException : Exception
	{
		private Dictionary<int, CodeInstruction> instructions;

		private int errorOffset;

		internal HarmonyException()
		{
		}

		internal HarmonyException(string message)
			: base(message)
		{
		}

		internal HarmonyException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		protected HarmonyException(SerializationInfo serializationInfo, StreamingContext streamingContext)
		{
			throw new NotImplementedException();
		}

		internal HarmonyException(Exception innerException, Dictionary<int, CodeInstruction> instructions, int errorOffset)
			: base("IL Compile Error", innerException)
		{
			this.instructions = instructions;
			this.errorOffset = errorOffset;
		}

		internal static Exception Create(Exception ex, MethodBody body)
		{
			Match match = Regex.Match(ex.Message.TrimEnd(new char[0]), "Reason: Invalid IL code in.+: IL_(\\d{4}): (.+)$");
			if (!match.Success)
			{
				return new HarmonyException("IL Compile Error (unknown location)", ex);
			}
			Dictionary<int, CodeInstruction> dictionary = ILManipulator.GetInstructions(body) ?? new Dictionary<int, CodeInstruction>();
			int num = int.Parse(match.Groups[1].Value, NumberStyles.HexNumber);
			Regex.Replace(match.Groups[2].Value, " {2,}", " ");
			if (ex is HarmonyException ex2)
			{
				if (dictionary.Count != 0)
				{
					ex2.instructions = dictionary;
					ex2.errorOffset = num;
				}
				return ex2;
			}
			return new HarmonyException(ex, dictionary, num);
		}

		public List<KeyValuePair<int, CodeInstruction>> GetInstructionsWithOffsets()
		{
			return instructions.OrderBy((KeyValuePair<int, CodeInstruction> ins) => ins.Key).ToList();
		}

		public List<CodeInstruction> GetInstructions()
		{
			return (from ins in instructions
				orderby ins.Key
				select ins.Value).ToList();
		}

		public int GetErrorOffset()
		{
			return errorOffset;
		}

		public int GetErrorIndex()
		{
			if (instructions.TryGetValue(errorOffset, out var value))
			{
				return GetInstructions().IndexOf(value);
			}
			return -1;
		}
	}
	public static class HarmonyGlobalSettings
	{
		public static bool DisallowLegacyGlobalUnpatchAll { get; set; }
	}
	public class HarmonyMethod
	{
		public MethodInfo method;

		public Type declaringType;

		public string methodName;

		public MethodType? methodType;

		public Type[] argumentTypes;

		public int priority = -1;

		public string[] before;

		public string[] after;

		public HarmonyReversePatchType? reversePatchType;

		public bool? debug;

		public string debugEmitPath;

		public bool nonVirtualDelegate;

		public bool? wrapTryCatch;

		internal string assemblyQualifiedDeclaringTypeName;

		public HarmonyMethod()
		{
		}

		private void ImportMethod(MethodInfo theMethod)
		{
			method = theMethod;
			if ((object)method != null)
			{
				List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod(method);
				if (fromMethod != null)
				{
					Merge(fromMethod).CopyTo(this);
				}
			}
		}

		public HarmonyMethod(MethodInfo method)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			ImportMethod(method);
		}

		public HarmonyMethod(MethodInfo method, int priority = -1, string[] before = null, string[] after = null, bool? debug = null)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			ImportMethod(method);
			this.priority = priority;
			this.before = before;
			this.after = after;
			this.debug = debug;
		}

		public HarmonyMethod(Type methodType, string methodName, Type[] argumentTypes = null)
		{
			MethodInfo methodInfo = AccessTools.Method(methodType, methodName, argumentTypes);
			if ((object)methodInfo == null)
			{
				throw new ArgumentException($"Cannot not find method for type {methodType} and name {methodName} and parameters {argumentTypes?.Description()}");
			}
			ImportMethod(methodInfo);
		}

		public static List<string> HarmonyFields()
		{
			return (from s in AccessTools.GetFieldNames(typeof(HarmonyMethod))
				where s != "method"
				select s).ToList();
		}

		public static HarmonyMethod Merge(List<HarmonyMethod> attributes)
		{
			return Merge((IEnumerable<HarmonyMethod>)attributes);
		}

		internal static HarmonyMethod Merge(IEnumerable<HarmonyMethod> attributes)
		{
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			if (attributes == null)
			{
				return harmonyMethod;
			}
			Traverse resultTrv = Traverse.Create(harmonyMethod);
			attributes.Do(delegate(HarmonyMethod attribute)
			{
				Traverse trv = Traverse.Create(attribute);
				HarmonyFields().ForEach(delegate(string f)
				{
					object value = trv.Field(f).GetValue();
					if (value != null && (f != "priority" || (int)value != -1))
					{
						HarmonyMethodExtensions.SetValue(resultTrv, f, value);
					}
				});
			});
			return harmonyMethod;
		}

		public override string ToString()
		{
			string result = "";
			Traverse trv = Traverse.Create(this);
			HarmonyFields().ForEach(delegate(string f)
			{
				if (result.Length > 0)
				{
					result += ", ";
				}
				result += $"{f}={trv.Field(f).GetValue()}";
			});
			return "HarmonyMethod[" + result + "]";
		}

		internal string Description()
		{
			string text = (((object)declaringType != null) ? declaringType.FullName : ((assemblyQualifiedDeclaringTypeName != null) ? assemblyQualifiedDeclaringTypeName : "undefined"));
			string text2 = methodName ?? "undefined";
			string text3 = (methodType.HasValue ? methodType.Value.ToString() : "undefined");
			string text4 = ((argumentTypes != null) ? argumentTypes.Description() : "undefined");
			return "(class=" + text + ", methodname=" + text2 + ", type=" + text3 + ", args=" + text4 + ")";
		}

		internal Type GetDeclaringType()
		{
			if ((object)declaringType == null && assemblyQualifiedDeclaringTypeName != null)
			{
				declaringType = Type.GetType(assemblyQualifiedDeclaringTypeName, throwOnError: true);
			}
			return declaringType;
		}

		internal Type[] GetArgumentList()
		{
			return argumentTypes ?? EmptyType.NoArgs;
		}
	}
	internal static class EmptyType
	{
		internal static readonly Type[] NoArgs = new Type[0];
	}
	public static class HarmonyMethodExtensions
	{
		internal static void SetValue(Traverse trv, string name, object val)
		{
			if (val != null)
			{
				Traverse traverse = trv.Field(name);
				if (name == "methodType" || name == "reversePatchType")
				{
					val = Enum.ToObject(Nullable.GetUnderlyingType(traverse.GetValueType()), (int)val);
				}
				traverse.SetValue(val);
			}
		}

		public static void CopyTo(this HarmonyMethod from, HarmonyMethod to)
		{
			if (to == null)
			{
				return;
			}
			Traverse fromTrv = Traverse.Create(from);
			Traverse toTrv = Traverse.Create(to);
			HarmonyMethod.HarmonyFields().ForEach(delegate(string f)
			{
				object value = fromTrv.Field(f).GetValue();
				if (value != null)
				{
					SetValue(toTrv, f, value);
				}
			});
		}

		public static HarmonyMethod Clone(this HarmonyMethod original)
		{
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			original.CopyTo(harmonyMethod);
			return harmonyMethod;
		}

		public static HarmonyMethod Merge(this HarmonyMethod master, HarmonyMethod detail)
		{
			if (detail == null)
			{
				return master;
			}
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			Traverse resultTrv = Traverse.Create(harmonyMethod);
			Traverse masterTrv = Traverse.Create(master);
			Traverse detailTrv = Traverse.Create(detail);
			HarmonyMethod.HarmonyFields().ForEach(delegate(string f)
			{
				object value = masterTrv.Field(f).GetValue();
				object value2 = detailTrv.Field(f).GetValue();
				if (f != "priority" || (int)value2 != -1)
				{
					SetValue(resultTrv, f, value2 ?? value);
				}
			});
			return harmonyMethod;
		}

		private static HarmonyMethod GetHarmonyMethodInfo(object attribute)
		{
			FieldInfo field = attribute.GetType().GetField("info", AccessTools.all);
			if ((object)field == null)
			{
				return null;
			}
			if (field.FieldType.FullName != typeof(HarmonyMethod).FullName)
			{
				return null;
			}
			return AccessTools.MakeDeepCopy<HarmonyMethod>(field.GetValue(attribute));
		}

		public static List<HarmonyMethod> GetFromType(Type type)
		{
			return (from attr in type.GetCustomAttributes(inherit: true)
				select GetHarmonyMethodInfo(attr) into info
				where info != null
				select info).ToList();
		}

		public static HarmonyMethod GetMergedFromType(Type type)
		{
			return HarmonyMethod.Merge(GetFromType(type));
		}

		public static List<HarmonyMethod> GetFromMethod(MethodBase method)
		{
			return (from attr in method.GetCustomAttributes(inherit: true)
				select GetHarmonyMethodInfo(attr) into info
				where info != null
				select info).ToList();
		}

		public static HarmonyMethod GetMergedFromMethod(MethodBase method)
		{
			return HarmonyMethod.Merge(GetFromMethod(method));
		}
	}
	public class InlineSignature : ICallSiteGenerator
	{
		public class ModifierType
		{
			public bool IsOptional;

			public Type Modifier;

			public object Type;

			public override string ToString()
			{
				return ((Type is Type type) ? type.FullDescription() : Type?.ToString()) + " mod" + (IsOptional ? "opt" : "req") + "(" + Modifier?.FullDescription() + ")";
			}

			internal TypeReference ToTypeReference(ModuleDefinition module)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Expected O, but got Unknown
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				if (!IsOptional)
				{
					return (TypeReference)new RequiredModifierType(module.ImportReference(Modifier), GetTypeReference(module, Type));
				}
				return (TypeReference)new OptionalModifierType(module.ImportReference(Modifier), GetTypeReference(module, Type));
			}
		}

		public bool HasThis { get; set; }

		public bool ExplicitThis { get; set; }

		public CallingConvention CallingConvention { get; set; } = CallingConvention.Winapi;


		public List<object> Parameters { get; set; } = new List<object>();


		public object ReturnType { get; set; } = typeof(void);


		public override string ToString()
		{
			return ((ReturnType is Type type) ? type.FullDescription() : ReturnType?.ToString()) + " (" + Parameters.Join((object p) => (!(p is Type type2)) ? p?.ToString() : type2.FullDescription()) + ")";
		}

		internal static TypeReference GetTypeReference(ModuleDefinition module, object param)
		{
			if (!(param is Type type))
			{
				if (!(param is InlineSignature inlineSignature))
				{
					if (param is ModifierType modifierType)
					{
						return modifierType.ToTypeReference(module);
					}
					throw new NotSupportedException($"Unsupported inline signature parameter type: {param} ({param?.GetType().FullDescription()})");
				}
				return (TypeReference)(object)inlineSignature.ToFunctionPointer(module);
			}
			return module.ImportReference(type);
		}

		CallSite ICallSiteGenerator.ToCallSite(ModuleDefinition module)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			CallSite val = new CallSite(GetTypeReference(module, ReturnType))
			{
				HasThis = HasThis,
				ExplicitThis = ExplicitThis,
				CallingConvention = (MethodCallingConvention)(byte)((byte)CallingConvention - 1)
			};
			foreach (object parameter in Parameters)
			{
				val.Parameters.Add(new ParameterDefinition(GetTypeReference(module, parameter)));
			}
			return val;
		}

		private FunctionPointerType ToFunctionPointer(ModuleDefinition module)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			FunctionPointerType val = new FunctionPointerType
			{
				ReturnType = GetTypeReference(module, ReturnType),
				HasThis = HasThis,
				ExplicitThis = ExplicitThis,
				CallingConvention = (MethodCallingConvention)(byte)((byte)CallingConvention - 1)
			};
			foreach (object parameter in Parameters)
			{
				val.Parameters.Add(new ParameterDefinition(GetTypeReference(module, parameter)));
			}
			return val;
		}
	}
	internal static class PatchInfoSerialization
	{
		private class Binder : SerializationBinder
		{
			public override Type BindToType(string assemblyName, string typeName)
			{
				Type[] array = new Type[3]
				{
					typeof(PatchInfo),
					typeof(Patch[]),
					typeof(Patch)
				};
				foreach (Type type in array)
				{
					if (typeName == type.FullName)
					{
						return type;
					}
				}
				return Type.GetType($"{typeName}, {assemblyName}");
			}
		}

		internal static byte[] Serialize(this PatchInfo patchInfo)
		{
			using MemoryStream memoryStream = new MemoryStream();
			new BinaryFormatter().Serialize(memoryStream, patchInfo);
			return memoryStream.GetBuffer();
		}

		internal static PatchInfo Deserialize(byte[] bytes)
		{
			BinaryFormatter obj = new BinaryFormatter
			{
				Binder = new Binder()
			};
			MemoryStream serializationStream = new MemoryStream(bytes);
			return (PatchInfo)obj.Deserialize(serializationStream);
		}

		internal static int PriorityComparer(object obj, int index, int priority)
		{
			Traverse traverse = Traverse.Create(obj);
			int value = traverse.Field("priority").GetValue<int>();
			int value2 = traverse.Field("index").GetValue<int>();
			if (priority != value)
			{
				return -priority.CompareTo(value);
			}
			return index.CompareTo(value2);
		}
	}
	[Serializable]
	public class PatchInfo
	{
		public Patch[] prefixes = new Patch[0];

		public Patch[] postfixes = new Patch[0];

		public Patch[] transpilers = new Patch[0];

		public Patch[] finalizers = new Patch[0];

		public Patch[] ilmanipulators = new Patch[0];

		public bool Debugging
		{
			get
			{
				if (!prefixes.Any((Patch p) => p.debug) && !postfixes.Any((Patch p) => p.debug) && !transpilers.Any((Patch p) => p.debug) && !finalizers.Any((Patch p) => p.debug))
				{
					return ilmanipulators.Any((Patch p) => p.debug);
				}
				return true;
			}
		}

		public string[] DebugEmitPaths => (from p in prefixes.Concat(postfixes).Concat(transpilers).Concat(finalizers)
				.Concat(ilmanipulators)
			select p.debugEmitPath into p
			where p != null
			select p).ToArray();

		internal void AddPrefixes(string owner, params HarmonyMethod[] methods)
		{
			prefixes = Add(owner, methods, prefixes);
		}

		[Obsolete("This method only exists for backwards compatibility since the class is public.")]
		public void AddPrefix(MethodInfo patch, string owner, int priority, string[] before, string[] after, bool debug)
		{
			AddPrefixes(owner, new HarmonyMethod(patch, priority, before, after, debug));
		}

		public void RemovePrefix(string owner)
		{
			prefixes = Remove(owner, prefixes);
		}

		internal void AddPostfixes(string owner, params HarmonyMethod[] methods)
		{
			postfixes = Add(owner, methods, postfixes);
		}

		[Obsolete("This method only exists for backwards compatibility since the class is public.")]
		public void AddPostfix(MethodInfo patch, string owner, int priority, string[] before, string[] after, bool debug)
		{
			AddPostfixes(owner, new HarmonyMethod(patch, priority, before, after, debug));
		}

		public void RemovePostfix(string owner)
		{
			postfixes = Remove(owner, postfixes);
		}

		internal void AddTranspilers(string owner, params HarmonyMethod[] methods)
		{
			transpilers = Add(owner, methods, transpilers);
		}

		[Obsolete("This method only exists for backwards compatibility since the class is public.")]
		public void AddTranspiler(MethodInfo patch, string owner, int priority, string[] before, string[] after, bool debug)
		{
			AddTranspilers(owner, new HarmonyMethod(patch, priority, before, after, debug));
		}

		public void RemoveTranspiler(string owner)
		{
			transpilers = Remove(owner, transpilers);
		}

		internal void AddFinalizers(string owner, params HarmonyMethod[] methods)
		{
			finalizers = Add(owner, methods, finalizers);
		}

		[Obsolete("This method only exists for backwards compatibility since the class is public.")]
		public void AddFinalizer(MethodInfo patch, string owner, int priority, string[] before, string[] after, bool debug)
		{
			AddFinalizers(owner, new HarmonyMethod(patch, priority, before, after, debug));
		}

		public void RemoveFinalizer(string owner)
		{
			finalizers = Remove(owner, finalizers);
		}

		internal void AddILManipulators(string owner, params HarmonyMethod[] methods)
		{
			ilmanipulators = Add(owner, methods, ilmanipulators);
		}

		public void RemoveILManipulator(string owner)
		{
			ilmanipulators = Remove(owner, ilmanipulators);
		}

		public void RemovePatch(MethodInfo patch)
		{
			prefixes = prefixes.Where((Patch p) => (object)p.PatchMethod != patch).ToArray();
			postfixes = postfixes.Where((Patch p) => (object)p.PatchMethod != patch).ToArray();
			transpilers = transpilers.Where((Patch p) => (object)p.PatchMethod != patch).ToArray();
			finalizers = finalizers.Where((Patch p) => (object)p.PatchMethod != patch).ToArray();
			ilmanipulators = ilmanipulators.Where((Patch p) => (object)p.PatchMethod != patch).ToArray();
		}

		private static Patch[] Add(string owner, HarmonyMethod[] add, Patch[] current)
		{
			if (add.Length == 0)
			{
				return current;
			}
			int initialIndex = current.Length;
			return current.Concat(add.Where((HarmonyMethod method) => method != null).Select((HarmonyMethod method, int i) => new Patch(method, i + initialIndex, owner))).ToArray();
		}

		private static Patch[] Remove(string owner, Patch[] current)
		{
			if (!(owner == "*"))
			{
				return current.Where((Patch patch) => patch.owner != owner).ToArray();
			}
			return new Patch[0];
		}
	}
	[Serializable]
	public class Patch : IComparable
	{
		public readonly int index;

		public readonly string owner;

		public readonly int priority;

		public readonly string[] before;

		public readonly string[] after;

		public readonly bool debug;

		public readonly string debugEmitPath;

		public readonly bool wrapTryCatch;

		[NonSerialized]
		private MethodInfo patchMethod;

		private int methodToken;

		private string moduleGUID;

		public MethodInfo PatchMethod
		{
			get
			{
				if ((object)patchMethod == null)
				{
					Module module = (from a in AppDomain.CurrentDomain.GetAssemblies()
						where !a.FullName.StartsWith("Microsoft.VisualStudio")
						select a).SelectMany((Assembly a) => a.GetLoadedModules()).First((Module m) => m.ModuleVersionId.ToString() == moduleGUID);
					patchMethod = (MethodInfo)module.ResolveMethod(methodToken);
				}
				return patchMethod;
			}
			set
			{
				patchMethod = value;
				methodToken = patchMethod.MetadataToken;
				moduleGUID = patchMethod.Module.ModuleVersionId.ToString();
			}
		}

		public Patch(MethodInfo patch, int index, string owner, int priority, string[] before, string[] after, bool debug)
		{
			if (patch is DynamicMethod)
			{
				throw new Exception("Cannot directly reference dynamic method \"" + patch.FullDescription() + "\" in Harmony. Use a factory method instead that will return the dynamic method.");
			}
			this.index = index;
			this.owner = owner;
			this.priority = ((priority == -1) ? 400 : priority);
			this.before = before ?? new string[0];
			this.after = after ?? new string[0];
			this.debug = debug;
			PatchMethod = patch;
		}

		public Patch(MethodInfo patch, int index, string owner, int priority, string[] before, string[] after, bool debug, bool wrapTryCatch)
		{
			if (patch is DynamicMethod)
			{
				throw new Exception("Cannot directly reference dynamic method \"" + patch.FullDescription() + "\" in Harmony. Use a factory method instead that will return the dynamic method.");
			}
			this.index = index;
			this.owner = owner;
			this.priority = ((priority == -1) ? 400 : priority);
			this.before = before ?? new string[0];
			this.after = after ?? new string[0];
			this.debug = debug;
			this.wrapTryCatch = wrapTryCatch;
			PatchMethod = patch;
		}

		public Patch(MethodInfo patch, int index, string owner, int priority, string[] before, string[] after, bool debug, bool wrapTryCatch, string debugEmitPath)
		{
			if (patch is DynamicMethod)
			{
				throw new Exception("Cannot directly reference dynamic method \"" + patch.FullDescription() + "\" in Harmony. Use a factory method instead that will return the dynamic method.");
			}
			this.index = index;
			this.owner = owner;
			this.priority = ((priority == -1) ? 400 : priority);
			this.before = before ?? new string[0];
			this.after = after ?? new string[0];
			this.debug = debug;
			this.debugEmitPath = debugEmitPath;
			this.wrapTryCatch = wrapTryCatch;
			PatchMethod = patch;
		}

		public Patch(HarmonyMethod method, int index, string owner)
			: this(method.method, index, owner, method.priority, method.before, method.after, method.debug.GetValueOrDefault(), method.wrapTryCatch.GetValueOrDefault(), method.debugEmitPath)
		{
		}

		public MethodInfo GetMethod(MethodBase original)
		{
			MethodInfo methodInfo = PatchMethod;
			if ((object)methodInfo.ReturnType != typeof(DynamicMethod) && (object)methodInfo.ReturnType != typeof(MethodInfo))
			{
				return methodInfo;
			}
			if (!methodInfo.IsStatic)
			{
				return methodInfo;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length != 1)
			{
				return methodInfo;
			}
			if ((object)parameters[0].ParameterType != typeof(MethodBase))
			{
				return methodInfo;
			}
			return methodInfo.Invoke(null, new object[1] { original }) as MethodInfo;
		}

		public override bool Equals(object obj)
		{
			if (obj != null && obj is Patch)
			{
				return (object)PatchMethod == ((Patch)obj).PatchMethod;
			}
			return false;
		}

		public int CompareTo(object obj)
		{
			return PatchInfoSerialization.PriorityComparer(obj, index, priority);
		}

		public override int GetHashCode()
		{
			return PatchMethod.GetHashCode();
		}
	}
	public class PatchClassProcessor
	{
		private readonly Harmony instance;

		private readonly Type containerType;

		private readonly HarmonyMethod containerAttributes;

		private readonly Dictionary<Type, MethodInfo> auxilaryMethods;

		private readonly List<AttributePatch> patchMethods;

		private static readonly List<Type> auxilaryTypes = new List<Type>
		{
			typeof(HarmonyPrepare),
			typeof(HarmonyCleanup),
			typeof(HarmonyTargetMethod),
			typeof(HarmonyTargetMethods)
		};

		public PatchClassProcessor(Harmony instance, Type type)
			: this(instance, type, allowUnannotatedType: false)
		{
		}

		public PatchClassProcessor(Harmony instance, Type type, bool allowUnannotatedType)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			this.instance = instance;
			containerType = type;
			List<HarmonyMethod> fromType = HarmonyMethodExtensions.GetFromType(type);
			if (!allowUnannotatedType && (fromType == null || fromType.Count == 0))
			{
				return;
			}
			containerAttributes = HarmonyMethod.Merge(fromType);
			MethodType? methodType = containerAttributes.methodType;
			if (!methodType.HasValue)
			{
				containerAttributes.methodType = MethodType.Normal;
			}
			auxilaryMethods = new Dictionary<Type, MethodInfo>();
			foreach (Type auxilaryType in auxilaryTypes)
			{
				MethodInfo patchMethod = PatchTools.GetPatchMethod(containerType, auxilaryType.FullName);
				if ((object)patchMethod != null)
				{
					auxilaryMethods[auxilaryType] = patchMethod;
				}
			}
			patchMethods = PatchTools.GetPatchMethods(containerType, (object)containerAttributes.GetDeclaringType() != null);
			foreach (AttributePatch patchMethod2 in patchMethods)
			{
				MethodInfo method = patchMethod2.info.method;
				patchMethod2.info = containerAttributes.Merge(patchMethod2.info);
				patchMethod2.info.method = method;
			}
		}

		public List<MethodInfo> Patch()
		{
			if (containerAttributes == null)
			{
				return null;
			}
			Exception exception = null;
			if (!RunMethod<HarmonyPrepare, bool>(defaultIfNotExisting: true, defaultIfFailing: false, null, new object[0]))
			{
				RunMethod<HarmonyCleanup>(ref exception, new object[0]);
				ReportException(exception, null);
				return new List<MethodInfo>();
			}
			List<MethodInfo> result = new List<MethodInfo>();
			MethodBase lastOriginal = null;
			try
			{
				List<MethodBase> bulkMethods = GetBulkMethods();
				if (bulkMethods.Count == 1)
				{
					lastOriginal = bulkMethods[0];
				}
				ReversePatch(ref lastOriginal);
				result = ((bulkMethods.Count > 0) ? BulkPatch(bulkMethods, ref lastOriginal) : PatchWithAttributes(ref lastOriginal));
			}
			catch (Exception ex)
			{
				exception = ex;
			}
			RunMethod<HarmonyCleanup>(ref exception, new object[1] { exception });
			ReportException(exception, lastOriginal);
			return result;
		}

		private void ReversePatch(ref MethodBase lastOriginal)
		{
			for (int i = 0; i < patchMethods.Count; i++)
			{
				AttributePatch attributePatch = patchMethods[i];
				if (attributePatch.type == HarmonyPatchType.ReversePatch)
				{
					MethodBase originalMethod = attributePatch.info.GetOriginalMethod();
					if ((object)originalMethod != null)
					{
						lastOriginal = originalMethod;
					}
					ReversePatcher reversePatcher = instance.CreateReversePatcher(lastOriginal, attributePatch.info);
					lock (PatchProcessor.locker)
					{
						reversePatcher.Patch();
					}
				}
			}
		}

		private List<MethodInfo> BulkPatch(List<MethodBase> originals, ref MethodBase lastOriginal)
		{
			PatchJobs<MethodInfo> patchJobs = new PatchJobs<MethodInfo>();
			for (int i = 0; i < originals.Count; i++)
			{
				lastOriginal = originals[i];
				PatchJobs<MethodInfo>.Job job = patchJobs.GetJob(lastOriginal);
				foreach (AttributePatch patchMethod in patchMethods)
				{
					string text = "You cannot combine TargetMethod, TargetMethods or [HarmonyPatchAll] with individual annotations";
					HarmonyMethod info = patchMethod.info;
					if (info.methodName != null)
					{
						throw new ArgumentException(text + " [" + info.methodName + "]");
					}
					if (info.methodType.HasValue && info.methodType.Value != 0)
					{
						throw new ArgumentException($"{text} [{info.methodType}]");
					}
					if (info.argumentTypes != null)
					{
						throw new ArgumentException(text + " [" + info.argumentTypes.Description() + "]");
					}
					job.AddPatch(patchMethod);
				}
			}
			foreach (PatchJobs<MethodInfo>.Job job2 in patchJobs.GetJobs())
			{
				lastOriginal = job2.original;
				ProcessPatchJob(job2);
			}
			return patchJobs.GetReplacements();
		}

		private List<MethodInfo> PatchWithAttributes(ref MethodBase lastOriginal)
		{
			PatchJobs<MethodInfo> patchJobs = new PatchJobs<MethodInfo>();
			foreach (AttributePatch patchMethod in patchMethods)
			{
				lastOriginal = patchMethod.info.GetOriginalMethod();
				if ((object)lastOriginal == null)
				{
					throw new ArgumentException("Undefined target method for patch method " + patchMethod.info.method.FullDescription());
				}
				patchJobs.GetJob(lastOriginal).AddPatch(patchMethod);
			}
			foreach (PatchJob

BepInEx/core/0Harmony20.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using HarmonyLib.Internal;
using HarmonyLib.Internal.Patching;
using HarmonyLib.Internal.Util;
using HarmonyLib.Tools;
using HarmonyXInterop;
using JetBrains.Annotations;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using MonoMod.Utils.Cil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HarmonyX2Interop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HarmonyX2Interop")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("69F6541D-A0F5-419D-B0EE-F5017F1D34F3")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
namespace JetBrains.Annotations
{
	[AttributeUsage(AttributeTargets.All)]
	internal sealed class UsedImplicitlyAttribute : Attribute
	{
		public ImplicitUseKindFlags UseKindFlags { get; }

		public ImplicitUseTargetFlags TargetFlags { get; }

		public UsedImplicitlyAttribute()
			: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
			: this(useKindFlags, ImplicitUseTargetFlags.Default)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
			: this(ImplicitUseKindFlags.Default, targetFlags)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
		{
			UseKindFlags = useKindFlags;
			TargetFlags = targetFlags;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter | AttributeTargets.GenericParameter)]
	internal sealed class MeansImplicitUseAttribute : Attribute
	{
		[UsedImplicitly]
		public ImplicitUseKindFlags UseKindFlags { get; }

		[UsedImplicitly]
		public ImplicitUseTargetFlags TargetFlags { get; }

		public MeansImplicitUseAttribute()
			: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
			: this(useKindFlags, ImplicitUseTargetFlags.Default)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
			: this(ImplicitUseKindFlags.Default, targetFlags)
		{
		}

		public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
		{
			UseKindFlags = useKindFlags;
			TargetFlags = targetFlags;
		}
	}
	[Flags]
	internal enum ImplicitUseKindFlags
	{
		Default = 7,
		Access = 1,
		Assign = 2,
		InstantiatedWithFixedConstructorSignature = 4,
		InstantiatedNoFixedConstructorSignature = 8
	}
	[Flags]
	internal enum ImplicitUseTargetFlags
	{
		Default = 1,
		Itself = 1,
		Members = 2,
		WithInheritors = 4,
		WithMembers = 3
	}
}
namespace HarmonyLib
{
	public static class Priority
	{
		public const int Last = 0;

		public const int VeryLow = 100;

		public const int Low = 200;

		public const int LowerThanNormal = 300;

		public const int Normal = 400;

		public const int HigherThanNormal = 500;

		public const int High = 600;

		public const int VeryHigh = 700;

		public const int First = 800;
	}
	public enum MethodType
	{
		Normal,
		Getter,
		Setter,
		Constructor,
		StaticConstructor
	}
	public enum ArgumentType
	{
		Normal,
		Ref,
		Out,
		Pointer
	}
	public enum HarmonyPatchType
	{
		All,
		Prefix,
		Postfix,
		Transpiler,
		Finalizer,
		ReversePatch
	}
	public enum HarmonyReversePatchType
	{
		Original,
		Snapshot
	}
	[MeansImplicitUse]
	public class HarmonyAttribute : Attribute
	{
		public HarmonyMethod info = new HarmonyMethod();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
	public class HarmonyPatch : HarmonyAttribute
	{
		public HarmonyPatch()
		{
		}

		public HarmonyPatch(Type declaringType)
		{
			info.declaringType = declaringType;
		}

		public HarmonyPatch(Type declaringType, Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, string methodName)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
		}

		public HarmonyPatch(Type declaringType, string methodName, params Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(Type declaringType, MethodType methodType)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
		}

		public HarmonyPatch(Type declaringType, MethodType methodType, params Type[] argumentTypes)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type declaringType, MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.declaringType = declaringType;
			info.methodType = methodType;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(Type declaringType, string methodName, MethodType methodType)
		{
			info.declaringType = declaringType;
			info.methodName = methodName;
			info.methodType = methodType;
		}

		public HarmonyPatch(string methodName)
		{
			info.methodName = methodName;
		}

		public HarmonyPatch(string methodName, params Type[] argumentTypes)
		{
			info.methodName = methodName;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.methodName = methodName;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(string methodName, MethodType methodType)
		{
			info.methodName = methodName;
			info.methodType = methodType;
		}

		public HarmonyPatch(MethodType methodType)
		{
			info.methodType = methodType;
		}

		public HarmonyPatch(MethodType methodType, params Type[] argumentTypes)
		{
			info.methodType = methodType;
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			info.methodType = methodType;
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		public HarmonyPatch(Type[] argumentTypes)
		{
			info.argumentTypes = argumentTypes;
		}

		public HarmonyPatch(Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			ParseSpecialArguments(argumentTypes, argumentVariations);
		}

		private void ParseSpecialArguments(Type[] argumentTypes, ArgumentType[] argumentVariations)
		{
			if (argumentVariations == null || argumentVariations.Length == 0)
			{
				info.argumentTypes = argumentTypes;
				return;
			}
			if (argumentTypes.Length < argumentVariations.Length)
			{
				throw new ArgumentException("argumentVariations contains more elements than argumentTypes", "argumentVariations");
			}
			List<Type> list = new List<Type>();
			for (int i = 0; i < argumentTypes.Length; i++)
			{
				Type type = argumentTypes[i];
				switch (argumentVariations[i])
				{
				case ArgumentType.Ref:
				case ArgumentType.Out:
					type = type.MakeByRefType();
					break;
				case ArgumentType.Pointer:
					type = type.MakePointerType();
					break;
				}
				list.Add(type);
			}
			info.argumentTypes = list.ToArray();
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
	public class HarmonyReversePatch : HarmonyAttribute
	{
		public HarmonyReversePatch(HarmonyReversePatchType type = HarmonyReversePatchType.Original)
		{
			info.reversePatchType = type;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class HarmonyPatchAll : HarmonyAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyPriority : HarmonyAttribute
	{
		public HarmonyPriority(int priority)
		{
			info.priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyBefore : HarmonyAttribute
	{
		public HarmonyBefore(params string[] before)
		{
			info.before = before;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
	public class HarmonyAfter : HarmonyAttribute
	{
		public HarmonyAfter(params string[] after)
		{
			info.after = after;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPrepare : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyCleanup : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTargetMethod : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTargetMethods : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPrefix : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyPostfix : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyTranspiler : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class HarmonyFinalizer : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = true)]
	public class HarmonyArgument : Attribute
	{
		public string OriginalName { get; private set; }

		public int Index { get; private set; }

		public string NewName { get; private set; }

		public HarmonyArgument(string originalName)
			: this(originalName, null)
		{
		}

		public HarmonyArgument(int index)
			: this(index, null)
		{
		}

		public HarmonyArgument(string originalName, string newName)
		{
			OriginalName = originalName;
			Index = -1;
			NewName = newName;
		}

		public HarmonyArgument(int index, string name)
		{
			OriginalName = null;
			Index = index;
			NewName = name;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class ParameterByRefAttribute : Attribute
	{
		public int[] ParameterIndices { get; }

		public ParameterByRefAttribute(params int[] parameterIndices)
		{
			ParameterIndices = parameterIndices;
		}
	}
	public class InvalidHarmonyPatchArgumentException : Exception
	{
		public MethodBase Original { get; }

		public MethodInfo Patch { get; }

		public override string Message => "(" + Extensions.GetID((MethodBase)Patch, (string)null, (string)null, true, false, false) + "): " + base.Message;

		public InvalidHarmonyPatchArgumentException(string message, MethodBase original, MethodInfo patch)
			: base(message)
		{
			Original = original;
			Patch = patch;
		}
	}
	public class MemberNotFoundException : Exception
	{
		public MemberNotFoundException(string message)
			: base(message)
		{
		}
	}
	public class Harmony
	{
		[Obsolete("No longer used, subscribe to Logger.LogChannel.Info")]
		public static bool DEBUG;

		[Obsolete("Not supported by HarmonyX", true)]
		public static bool SELF_PATCHING;

		public string Id { get; private set; }

		public Harmony(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("id cannot be null or empty");
			}
			Logger.Log(Logger.LogChannel.Info, delegate
			{
				Assembly assembly = typeof(Harmony).Assembly;
				Version version = assembly.GetName().Version;
				string text = assembly.Location;
				if (string.IsNullOrEmpty(text))
				{
					text = new Uri(assembly.CodeBase).LocalPath;
				}
				MethodBase outsideCaller = AccessTools.GetOutsideCaller();
				Assembly assembly2 = outsideCaller.DeclaringType?.Assembly;
				string text2 = assembly2?.Location;
				if (string.IsNullOrEmpty(text2))
				{
					text2 = (((object)assembly2 != null) ? new Uri(assembly2.CodeBase).LocalPath : string.Empty);
				}
				return $"Created Harmony instance id={id}, version={version}, location={text} - Started from {Extensions.GetID(outsideCaller, (string)null, (string)null, true, false, false)} location={text2}";
			});
			Id = id;
		}

		public void PatchAll()
		{
			Assembly assembly = new StackTrace().GetFrame(1).GetMethod().ReflectedType.Assembly;
			PatchAll(assembly);
		}

		public PatchProcessor ProcessorForAnnotatedClass(Type type)
		{
			List<HarmonyMethod> fromType = HarmonyMethodExtensions.GetFromType(type);
			if (fromType != null && fromType.Any())
			{
				HarmonyMethod attributes = HarmonyMethod.Merge(fromType);
				return new PatchProcessor(this, type, attributes);
			}
			return null;
		}

		public void PatchAll(Assembly assembly)
		{
			if ((object)assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			List<PatchProcessor> list = (from x in assembly.GetTypes().Select(ProcessorForAnnotatedClass)
				where x != null
				select x).ToList();
			foreach (PatchProcessor item in list)
			{
				item.Patch();
			}
			if (list.Count == 0)
			{
				Logger.Log(Logger.LogChannel.Warn, () => "Could not find any valid Harmony patches inside of assembly " + assembly.FullName);
			}
		}

		public DynamicMethod Patch(MethodBase original, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null)
		{
			PatchProcessor patchProcessor = new PatchProcessor(this, original);
			patchProcessor.AddPrefix(prefix);
			patchProcessor.AddPostfix(postfix);
			patchProcessor.AddTranspiler(transpiler);
			patchProcessor.AddFinalizer(finalizer);
			return patchProcessor.Patch().FirstOrDefault();
		}

		public MethodInfo ReversePatch(MethodBase original, HarmonyMethod standin, MethodInfo transpiler = null)
		{
			return null;
		}

		public ReversePatcher CreateReversePatcher(MethodBase original, MethodInfo standin)
		{
			return new ReversePatcher(this, original, standin);
		}

		public void UnpatchAll(string harmonyID = null)
		{
			foreach (MethodBase item in GetAllPatchedMethods().ToList())
			{
				Patches patchInfo = GetPatchInfo(item);
				UnpatchAllId(item, patchInfo.Prefixes);
				UnpatchAllId(item, patchInfo.Postfixes);
				UnpatchAllId(item, patchInfo.Transpilers);
				UnpatchAllId(item, patchInfo.Finalizers);
			}
			void UnpatchAllId(MethodBase original, IEnumerable<Patch> patches)
			{
				foreach (Patch patch in patches)
				{
					if (harmonyID == null || patch.owner == harmonyID)
					{
						Unpatch(original, patch.patch);
					}
				}
			}
		}

		public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyID = null)
		{
			new PatchProcessor(this, original).Unpatch(type, harmonyID);
		}

		public void Unpatch(MethodBase original, MethodInfo patch)
		{
			new PatchProcessor(this, original).Unpatch(patch);
		}

		public static bool HasAnyPatches(string harmonyID)
		{
			return GetAllPatchedMethods().Select(GetPatchInfo).Any((Patches info) => info.Owners.Contains(harmonyID));
		}

		public static Patches GetPatchInfo(MethodBase method)
		{
			return PatchProcessor.GetPatchInfo(method);
		}

		public IEnumerable<MethodBase> GetPatchedMethods()
		{
			return from original in GetAllPatchedMethods()
				where GetPatchInfo(original).Owners.Contains(Id)
				select original;
		}

		public static IEnumerable<MethodBase> GetAllPatchedMethods()
		{
			return GlobalPatchState.GetPatchedMethods();
		}

		public static Dictionary<string, Version> VersionInfo(out Version currentVersion)
		{
			return PatchProcessor.VersionInfo(out currentVersion);
		}

		public void PatchAll(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod(methodInfo);
				if (fromMethod != null && fromMethod.Any())
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(inherit: true);
					HarmonyMethod combinedInfo = HarmonyMethod.Merge(fromMethod);
					List<HarmonyMethod> list = fromMethod.Where(IsMethodComplete).ToList();
					if (fromMethod.All((HarmonyMethod x) => (object)x.declaringType != combinedInfo.declaringType && x.methodName != combinedInfo.methodName))
					{
						list.Add(combinedInfo);
					}
					List<MethodBase> list2 = new List<MethodBase>();
					foreach (HarmonyMethod item in list)
					{
						foreach (int item2 in customAttributes.OfType<ParameterByRefAttribute>().SelectMany((ParameterByRefAttribute x) => x.ParameterIndices))
						{
							if (!item.argumentTypes[item2].IsByRef)
							{
								item.argumentTypes[item2] = item.argumentTypes[item2].MakeByRefType();
							}
						}
						if (!item.methodType.HasValue)
						{
							item.methodType = MethodType.Normal;
						}
						if ((object)item.method == null)
						{
							item.method = methodInfo;
						}
						MethodBase originalMethod = PatchProcessor.GetOriginalMethod(item);
						if ((object)originalMethod != null)
						{
							list2.Add(originalMethod);
						}
					}
					PatchProcessor patchProcessor = new PatchProcessor(this);
					foreach (MethodBase item3 in list2)
					{
						patchProcessor.AddOriginal(item3);
					}
					if (customAttributes.Any((object x) => x is HarmonyPrefix))
					{
						patchProcessor.AddPrefix(new HarmonyMethod(methodInfo));
					}
					if (customAttributes.Any((object x) => x is HarmonyTranspiler))
					{
						patchProcessor.AddTranspiler(new HarmonyMethod(methodInfo));
					}
					if (customAttributes.Any((object x) => x is HarmonyPostfix))
					{
						patchProcessor.AddPostfix(new HarmonyMethod(methodInfo));
					}
					if (customAttributes.Any((object x) => x is HarmonyFinalizer))
					{
						patchProcessor.AddFinalizer(new HarmonyMethod(methodInfo));
					}
					patchProcessor.Patch();
				}
				else if ((Logger.ChannelFilter & Logger.LogChannel.Warn) != 0 && methodInfo.GetCustomAttributes(typeof(HarmonyAttribute), inherit: true).Any())
				{
					Logger.LogText(Logger.LogChannel.Warn, "Method " + methodInfo.FullDescription() + " has an invalid combination of Harmony attributes and will be ignored");
				}
			}
			static bool IsMethodComplete(HarmonyMethod m)
			{
				if ((object)m.declaringType != null)
				{
					if (m.methodName == null && m.methodType != MethodType.Constructor)
					{
						return m.methodType == MethodType.StaticConstructor;
					}
					return true;
				}
				return false;
			}
		}

		public static Harmony CreateAndPatchAll(Type type, string harmonyInstanceId = null)
		{
			Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Guid.NewGuid()}");
			harmony.PatchAll(type);
			return harmony;
		}

		public static Harmony CreateAndPatchAll(Assembly assembly, string harmonyInstanceId = null)
		{
			Harmony harmony = new Harmony(harmonyInstanceId ?? $"harmony-auto-{Guid.NewGuid()}");
			harmony.PatchAll(assembly);
			return harmony;
		}
	}
	public class HarmonyMethod
	{
		public MethodInfo method;

		public Type declaringType;

		public string methodName;

		public MethodType? methodType;

		public Type[] argumentTypes;

		public int priority = -1;

		public string[] before;

		public string[] after;

		public HarmonyReversePatchType? reversePatchType;

		public HarmonyMethod()
		{
		}

		private void ImportMethod(MethodInfo theMethod)
		{
			method = theMethod;
			if ((object)method != null)
			{
				List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod(method);
				if (fromMethod != null)
				{
					Merge(fromMethod).CopyTo(this);
				}
			}
		}

		public HarmonyMethod(MethodInfo method)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			ImportMethod(method);
		}

		public HarmonyMethod(Type type, string name, Type[] parameters = null)
		{
			MethodInfo methodInfo = AccessTools.Method(type, name, parameters);
			if ((object)methodInfo == null)
			{
				throw new ArgumentException($"Cannot not find method for type {type} and name {name} and parameters {parameters?.Description()}");
			}
			ImportMethod(methodInfo);
		}

		public static List<string> HarmonyFields()
		{
			return (from s in AccessTools.GetFieldNames(typeof(HarmonyMethod))
				where s != "method"
				select s).ToList();
		}

		public static HarmonyMethod Merge(List<HarmonyMethod> attributes)
		{
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			if (attributes == null)
			{
				return harmonyMethod;
			}
			Traverse resultTrv = Traverse.Create(harmonyMethod);
			attributes.ForEach(delegate(HarmonyMethod attribute)
			{
				Traverse trv = Traverse.Create(attribute);
				HarmonyFields().ForEach(delegate(string f)
				{
					object value = trv.Field(f).GetValue();
					if (value != null)
					{
						HarmonyMethodExtensions.SetValue(resultTrv, f, value);
					}
				});
			});
			return harmonyMethod;
		}

		public override string ToString()
		{
			string result = "HarmonyMethod[";
			Traverse trv = Traverse.Create(this);
			HarmonyFields().ForEach(delegate(string f)
			{
				result += $"{f}{'='}{trv.Field(f).GetValue()}";
			});
			return result + "]";
		}
	}
	public static class HarmonyMethodExtensions
	{
		internal static void SetValue(Traverse trv, string name, object val)
		{
			if (val != null)
			{
				Traverse traverse = trv.Field(name);
				if (name == "methodType" || name == "reversePatchType")
				{
					val = Enum.ToObject(Nullable.GetUnderlyingType(traverse.GetValueType()), (int)val);
				}
				traverse.SetValue(val);
			}
		}

		public static void CopyTo(this HarmonyMethod from, HarmonyMethod to)
		{
			if (to == null)
			{
				return;
			}
			Traverse fromTrv = Traverse.Create(from);
			Traverse toTrv = Traverse.Create(to);
			HarmonyMethod.HarmonyFields().ForEach(delegate(string f)
			{
				object value = fromTrv.Field(f).GetValue();
				if (value != null)
				{
					SetValue(toTrv, f, value);
				}
			});
		}

		public static HarmonyMethod Clone(this HarmonyMethod original)
		{
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			original.CopyTo(harmonyMethod);
			return harmonyMethod;
		}

		public static HarmonyMethod Merge(this HarmonyMethod master, HarmonyMethod detail)
		{
			if (detail == null)
			{
				return master;
			}
			HarmonyMethod harmonyMethod = new HarmonyMethod();
			Traverse resultTrv = Traverse.Create(harmonyMethod);
			Traverse masterTrv = Traverse.Create(master);
			Traverse detailTrv = Traverse.Create(detail);
			HarmonyMethod.HarmonyFields().ForEach(delegate(string f)
			{
				object value = masterTrv.Field(f).GetValue();
				object value2 = detailTrv.Field(f).GetValue();
				SetValue(resultTrv, f, value2 ?? value);
			});
			return harmonyMethod;
		}

		private static HarmonyMethod GetHarmonyMethodInfo(object attribute)
		{
			FieldInfo field = attribute.GetType().GetField("info", AccessTools.all);
			if ((object)field == null)
			{
				return null;
			}
			if (field.FieldType.Name != "HarmonyMethod")
			{
				return null;
			}
			return AccessTools.MakeDeepCopy<HarmonyMethod>(field.GetValue(attribute));
		}

		public static List<HarmonyMethod> GetFromType(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return (from attr in type.GetCustomAttributes(inherit: true)
				select GetHarmonyMethodInfo(attr) into info
				where info != null
				select info).ToList();
		}

		public static HarmonyMethod GetMergedFromType(Type type)
		{
			return HarmonyMethod.Merge(GetFromType(type));
		}

		public static HarmonyMethod GetMergedFromMethod(MethodBase method)
		{
			return HarmonyMethod.Merge(GetFromMethod(method));
		}

		public static List<HarmonyMethod> GetFromMethod(MethodBase method)
		{
			return (from attr in method.GetCustomAttributes(inherit: true)
				select GetHarmonyMethodInfo(attr) into info
				where info != null
				select info).ToList();
		}
	}
	[Obsolete("Exists for legacy support", true)]
	internal static class HarmonySharedState
	{
		[Obsolete("Exists for legacy support", true)]
		public static PatchInfo GetPatchInfo(MethodBase method)
		{
			return method.ToPatchInfo();
		}

		[Obsolete("Exists for legacy support", true)]
		public static IEnumerable<MethodBase> GetPatchedMethods()
		{
			return GlobalPatchState.GetPatchedMethods();
		}

		[Obsolete("Exists for legacy support", true)]
		public static void UpdatePatchInfo(MethodBase methodBase, PatchInfo patchInfo)
		{
		}
	}
	[Obsolete("Exists for legacy support", true)]
	internal static class PatchFunctions
	{
		[Obsolete("Exists for legacy support", true)]
		public static DynamicMethod UpdateWrapper(MethodBase original, PatchInfo info, string id)
		{
			original.GetMethodPatcher().Apply();
			return null;
		}
	}
	public class PatchInfo
	{
		public Patch[] prefixes;

		public Patch[] postfixes;

		public Patch[] transpilers;

		public Patch[] finalizers;

		public PatchInfo()
		{
			prefixes = new Patch[0];
			postfixes = new Patch[0];
			transpilers = new Patch[0];
			finalizers = new Patch[0];
		}

		private void AddPatch(ref Patch[] list, string owner, HarmonyMethod info)
		{
			if ((object)info?.method != null)
			{
				int priority = ((info.priority == -1) ? 400 : info.priority);
				string[] before = info.before ?? new string[0];
				string[] after = info.after ?? new string[0];
				AddPatch(ref list, info.method, owner, priority, before, after);
			}
		}

		private void AddPatch(ref Patch[] list, MethodInfo patch, string owner, int priority, string[] before, string[] after)
		{
			List<Patch> list2 = list.ToList();
			list2.Add(new Patch(patch, prefixes.Count() + 1, owner, priority, before, after));
			list = list2.ToArray();
		}

		private void RemovePatch(ref Patch[] list, string owner)
		{
			if (owner == "*")
			{
				list = new Patch[0];
				return;
			}
			list = list.Where((Patch patch) => patch.owner != owner).ToArray();
		}

		public void AddPrefix(MethodInfo patch, string owner, int priority, string[] before, string[] after)
		{
			AddPatch(ref prefixes, patch, owner, priority, before, after);
		}

		public void AddPrefix(string owner, HarmonyMethod info)
		{
			AddPatch(ref prefixes, owner, info);
		}

		public void RemovePrefix(string owner)
		{
			RemovePatch(ref prefixes, owner);
		}

		public void AddPostfix(MethodInfo patch, string owner, int priority, string[] before, string[] after)
		{
			AddPatch(ref postfixes, patch, owner, priority, before, after);
		}

		public void AddPostfix(string owner, HarmonyMethod info)
		{
			AddPatch(ref postfixes, owner, info);
		}

		public void RemovePostfix(string owner)
		{
			RemovePatch(ref postfixes, owner);
		}

		public void AddTranspiler(MethodInfo patch, string owner, int priority, string[] before, string[] after)
		{
			AddPatch(ref transpilers, patch, owner, priority, before, after);
		}

		public void AddTranspiler(string owner, HarmonyMethod info)
		{
			AddPatch(ref transpilers, owner, info);
		}

		public void RemoveTranspiler(string owner)
		{
			RemovePatch(ref transpilers, owner);
		}

		public void AddFinalizer(MethodInfo patch, string owner, int priority, string[] before, string[] after)
		{
			AddPatch(ref finalizers, patch, owner, priority, before, after);
		}

		public void AddFinalizer(string owner, HarmonyMethod info)
		{
			AddPatch(ref finalizers, owner, info);
		}

		public void RemoveFinalizer(string owner)
		{
			RemovePatch(ref finalizers, owner);
		}

		public void RemovePatch(MethodInfo patch)
		{
			lock (this)
			{
				prefixes = prefixes.Where((Patch p) => (object)p.patch != patch).ToArray();
				postfixes = postfixes.Where((Patch p) => (object)p.patch != patch).ToArray();
				transpilers = transpilers.Where((Patch p) => (object)p.patch != patch).ToArray();
				finalizers = finalizers.Where((Patch p) => (object)p.patch != patch).ToArray();
			}
		}
	}
	public class Patch : IComparable
	{
		public readonly int index;

		public readonly string owner;

		public readonly int priority;

		public readonly string[] before;

		public readonly string[] after;

		public MethodInfo patch;

		public MethodInfo PatchMethod
		{
			get
			{
				return patch;
			}
			set
			{
				patch = value;
			}
		}

		public Patch(MethodInfo patch, int index, string owner, int priority, string[] before, string[] after)
		{
			if (patch is DynamicMethod)
			{
				throw new ArgumentException("Cannot directly reference dynamic method \"" + Extensions.GetID((MethodBase)patch, (string)null, (string)null, true, false, false) + "\" in Harmony. Use a factory method instead that will return the dynamic method.", "patch");
			}
			this.index = index;
			this.owner = owner;
			this.priority = priority;
			this.before = before;
			this.after = after;
			this.patch = patch;
		}

		public MethodInfo GetMethod(MethodBase original)
		{
			if ((object)patch.ReturnType != typeof(DynamicMethod) && (object)patch.ReturnType != typeof(MethodInfo))
			{
				return patch;
			}
			if (!patch.IsStatic)
			{
				return patch;
			}
			ParameterInfo[] parameters = patch.GetParameters();
			if (parameters.Count() != 1)
			{
				return patch;
			}
			if ((object)parameters[0].ParameterType != typeof(MethodBase))
			{
				return patch;
			}
			return patch.Invoke(null, new object[1] { original }) as MethodInfo;
		}

		public override bool Equals(object obj)
		{
			if (obj is Patch patch)
			{
				return (object)this.patch == patch.patch;
			}
			return false;
		}

		public int CompareTo(object obj)
		{
			if (!(obj is Patch patch))
			{
				return 0;
			}
			int num;
			if (patch.priority != priority)
			{
				num = priority;
				return -num.CompareTo(patch.priority);
			}
			num = index;
			return num.CompareTo(patch.index);
		}

		public override int GetHashCode()
		{
			return patch.GetHashCode();
		}
	}
	public class Patches
	{
		public readonly ReadOnlyCollection<Patch> Prefixes;

		public readonly ReadOnlyCollection<Patch> Postfixes;

		public readonly ReadOnlyCollection<Patch> Transpilers;

		public readonly ReadOnlyCollection<Patch> Finalizers;

		public ReadOnlyCollection<string> Owners
		{
			get
			{
				HashSet<string> hashSet = new HashSet<string>();
				hashSet.UnionWith(Prefixes.Select((Patch p) => p.owner));
				hashSet.UnionWith(Postfixes.Select((Patch p) => p.owner));
				hashSet.UnionWith(Transpilers.Select((Patch p) => p.owner));
				hashSet.UnionWith(Finalizers.Select((Patch p) => p.owner));
				return hashSet.ToList().AsReadOnly();
			}
		}

		public Patches(Patch[] prefixes, Patch[] postfixes, Patch[] transpilers, Patch[] finalizers)
		{
			if (prefixes == null)
			{
				prefixes = new Patch[0];
			}
			if (postfixes == null)
			{
				postfixes = new Patch[0];
			}
			if (transpilers == null)
			{
				transpilers = new Patch[0];
			}
			if (finalizers == null)
			{
				finalizers = new Patch[0];
			}
			Prefixes = prefixes.ToList().AsReadOnly();
			Postfixes = postfixes.ToList().AsReadOnly();
			Transpilers = transpilers.ToList().AsReadOnly();
			Finalizers = finalizers.ToList().AsReadOnly();
		}
	}
	public class PatchProcessor
	{
		private readonly Harmony instance;

		private readonly Type container;

		private readonly HarmonyMethod containerAttributes;

		private readonly List<MethodBase> originals = new List<MethodBase>();

		private HarmonyMethod prefix;

		private HarmonyMethod postfix;

		private HarmonyMethod transpiler;

		private HarmonyMethod finalizer;

		public PatchProcessor(Harmony instance, MethodBase original = null)
		{
			this.instance = instance;
			if ((object)original != null)
			{
				originals.Add(original);
			}
		}

		public PatchProcessor(Harmony instance, Type type, HarmonyMethod attributes)
		{
			this.instance = instance;
			container = type;
			containerAttributes = attributes ?? new HarmonyMethod();
			prefix = containerAttributes.Clone();
			postfix = containerAttributes.Clone();
			transpiler = containerAttributes.Clone();
			finalizer = containerAttributes.Clone();
			PrepareType();
		}

		[Obsolete("Use other constructors and Add* methods")]
		public PatchProcessor(Harmony instance, List<MethodBase> originals, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null)
		{
			this.instance = instance;
			this.originals = originals;
			this.prefix = prefix;
			this.postfix = postfix;
			this.transpiler = transpiler;
			this.finalizer = finalizer;
		}

		public PatchProcessor AddOriginal(MethodBase original)
		{
			if (!originals.Contains(original))
			{
				originals.Add(original);
			}
			return this;
		}

		public PatchProcessor SetOriginals(List<MethodBase> originals)
		{
			this.originals.Clear();
			this.originals.AddRange(originals);
			return this;
		}

		public PatchProcessor AddPrefix(HarmonyMethod prefix)
		{
			this.prefix = prefix;
			return this;
		}

		public PatchProcessor AddPrefix(MethodInfo fixMethod)
		{
			prefix = new HarmonyMethod(fixMethod);
			return this;
		}

		public PatchProcessor AddPostfix(HarmonyMethod postfix)
		{
			this.postfix = postfix;
			return this;
		}

		public PatchProcessor AddPostfix(MethodInfo fixMethod)
		{
			postfix = new HarmonyMethod(fixMethod);
			return this;
		}

		public PatchProcessor AddTranspiler(HarmonyMethod transpiler)
		{
			this.transpiler = transpiler;
			return this;
		}

		public PatchProcessor AddTranspiler(MethodInfo fixMethod)
		{
			transpiler = new HarmonyMethod(fixMethod);
			return this;
		}

		public PatchProcessor AddFinalizer(HarmonyMethod finalizer)
		{
			this.finalizer = finalizer;
			return this;
		}

		public PatchProcessor AddFinalizer(MethodInfo fixMethod)
		{
			finalizer = new HarmonyMethod(fixMethod);
			return this;
		}

		public static Patches GetPatchInfo(MethodBase method)
		{
			PatchInfo patchInfo = method.GetPatchInfo();
			if (patchInfo == null)
			{
				return null;
			}
			lock (patchInfo)
			{
				return new Patches(patchInfo.prefixes, patchInfo.postfixes, patchInfo.transpilers, patchInfo.finalizers);
			}
		}

		public static Dictionary<string, Version> VersionInfo(out Version currentVersion)
		{
			currentVersion = typeof(Harmony).Assembly.GetName().Version;
			Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
			foreach (MethodBase allPatchedMethod in GetAllPatchedMethods())
			{
				Patches patchInfo = GetPatchInfo(allPatchedMethod);
				AddAssemblies(patchInfo.Prefixes);
				AddAssemblies(patchInfo.Postfixes);
				AddAssemblies(patchInfo.Transpilers);
				AddAssemblies(patchInfo.Finalizers);
			}
			Dictionary<string, Version> dictionary = new Dictionary<string, Version>();
			foreach (KeyValuePair<string, Assembly> item in assemblies)
			{
				AssemblyName assemblyName = item.Value.GetReferencedAssemblies().FirstOrDefault((AssemblyName a) => a.FullName.StartsWith("0Harmony, Version", StringComparison.Ordinal));
				if (assemblyName != null)
				{
					dictionary[item.Key] = assemblyName.Version;
				}
			}
			return dictionary;
			void AddAssemblies(IEnumerable<Patch> patches)
			{
				foreach (Patch patch in patches)
				{
					assemblies[patch.owner] = patch.patch.DeclaringType?.Assembly;
				}
			}
		}

		public static List<CodeInstruction> GetOriginalInstructions(MethodBase original, ILGenerator generator = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			DynamicMethodDefinition val = new DynamicMethodDefinition(original);
			ILManipulator iLManipulator = new ILManipulator(val.Definition.Body);
			ILGenerator il = generator ?? ((ILGeneratorShim)new CecilILGenerator(val.GetILProcessor())).GetProxy();
			return iLManipulator.GetInstructions(il);
		}

		public static List<CodeInstruction> GetOriginalInstructions(MethodBase original, out ILGenerator generator)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			DynamicMethodDefinition val = new DynamicMethodDefinition(original);
			ILManipulator iLManipulator = new ILManipulator(val.Definition.Body);
			generator = ((ILGeneratorShim)new CecilILGenerator(val.GetILProcessor())).GetProxy();
			return iLManipulator.GetInstructions(generator);
		}

		[Obsolete("Use GetAllPatchedMethods instead")]
		public static IEnumerable<MethodBase> AllPatchedMethods()
		{
			return GlobalPatchState.GetPatchedMethods();
		}

		public static IEnumerable<MethodBase> GetAllPatchedMethods()
		{
			return GlobalPatchState.GetPatchedMethods();
		}

		public List<DynamicMethod> Patch()
		{
			Stopwatch sw = null;
			Logger.Log(Logger.LogChannel.Info, delegate
			{
				sw = Stopwatch.StartNew();
				return "Patching " + instance.Id + "...";
			});
			List<DynamicMethod> result = new List<DynamicMethod>();
			foreach (MethodBase original in originals)
			{
				if ((object)original == null)
				{
					throw new NullReferenceException("Null method for " + instance.Id);
				}
				Logger.Log(Logger.LogChannel.Info, () => "Patching " + Extensions.GetID(original, (string)null, (string)null, true, false, false));
				bool individualPrepareResult = RunMethod<HarmonyPrepare, bool>(defaultIfNotExisting: true, new object[1] { original });
				Logger.Log(Logger.LogChannel.Info, () => $"HarmonyPrepare result: {individualPrepareResult}");
				if (individualPrepareResult)
				{
					PatchInfo patchInfo = original.ToPatchInfo();
					lock (patchInfo)
					{
						patchInfo.AddPrefix(instance.Id, prefix);
						patchInfo.AddPostfix(instance.Id, postfix);
						patchInfo.AddTranspiler(instance.Id, transpiler);
						patchInfo.AddFinalizer(instance.Id, finalizer);
					}
					original.GetMethodPatcher().Apply();
					RunMethod<HarmonyCleanup>(new object[1] { original });
				}
			}
			Logger.Log(Logger.LogChannel.Info, () => $"Patching {instance.Id} took {sw.ElapsedMilliseconds}ms");
			return result;
		}

		public PatchProcessor Unpatch(HarmonyPatchType type, string harmonyID)
		{
			foreach (MethodBase original in originals)
			{
				PatchInfo patchInfo = original.ToPatchInfo();
				lock (patchInfo)
				{
					if (type == HarmonyPatchType.All || type == HarmonyPatchType.Prefix)
					{
						patchInfo.RemovePrefix(harmonyID);
					}
					if (type == HarmonyPatchType.All || type == HarmonyPatchType.Postfix)
					{
						patchInfo.RemovePostfix(harmonyID);
					}
					if (type == HarmonyPatchType.All || type == HarmonyPatchType.Transpiler)
					{
						patchInfo.RemoveTranspiler(harmonyID);
					}
					if (type == HarmonyPatchType.All || type == HarmonyPatchType.Finalizer)
					{
						patchInfo.RemoveFinalizer(harmonyID);
					}
				}
				original.GetMethodPatcher().Apply();
			}
			return this;
		}

		public PatchProcessor Unpatch(MethodInfo patch)
		{
			foreach (MethodBase original in originals)
			{
				original.ToPatchInfo().RemovePatch(patch);
				original.GetMethodPatcher().Apply();
			}
			return this;
		}

		private void PrepareType()
		{
			if (!RunMethod<HarmonyPrepare, bool>(defaultIfNotExisting: true, new object[0]))
			{
				return;
			}
			MethodType? methodType = containerAttributes.methodType;
			if (!containerAttributes.methodType.HasValue)
			{
				containerAttributes.methodType = MethodType.Normal;
			}
			string reversePatchAttr = typeof(HarmonyReversePatch).FullName;
			foreach (MethodInfo item in (from m in container.GetMethods(AccessTools.all)
				where m.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().FullName == reversePatchAttr)
				select m).ToList())
			{
				MethodBase originalMethod = GetOriginalMethod(containerAttributes.Merge(new HarmonyMethod(item)));
				instance.CreateReversePatcher(originalMethod, item).Patch();
			}
			IEnumerable<MethodBase> enumerable = RunMethod<HarmonyTargetMethods, IEnumerable<MethodBase>>(null, new object[0]);
			if (enumerable != null)
			{
				originals.Clear();
				originals.AddRange(enumerable);
			}
			else if (container.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().FullName == typeof(HarmonyPatchAll).FullName))
			{
				Type declaringType = containerAttributes.declaringType;
				originals.AddRange(AccessTools.GetDeclaredConstructors(declaringType).Cast<MethodBase>());
				originals.AddRange(AccessTools.GetDeclaredMethods(declaringType).Cast<MethodBase>());
				List<PropertyInfo> declaredProperties = AccessTools.GetDeclaredProperties(declaringType);
				originals.AddRange((from prop in declaredProperties
					select prop.GetGetMethod(nonPublic: true) into method
					where (object)method != null
					select method).Cast<MethodBase>());
				originals.AddRange((from prop in declaredProperties
					select prop.GetSetMethod(nonPublic: true) into method
					where (object)method != null
					select method).Cast<MethodBase>());
			}
			else
			{
				MethodBase methodBase = RunMethod<HarmonyTargetMethod, MethodBase>(null, new object[0]) ?? GetOriginalMethod(containerAttributes);
				if ((object)methodBase == null)
				{
					string text = "(";
					text += $"declaringType={containerAttributes.declaringType}, ";
					text = text + "methodName =" + containerAttributes.methodName + ", ";
					text += $"methodType={methodType}, ";
					text = text + "argumentTypes=" + containerAttributes.argumentTypes.Description();
					text += ")";
					throw new ArgumentException("No target method specified for class " + container.FullName + " " + text);
				}
				originals.Add(methodBase);
			}
			GetPatches(container, out var methodInfo, out var methodInfo2, out var methodInfo3, out var methodInfo4);
			if (prefix != null)
			{
				prefix.method = methodInfo;
			}
			if (postfix != null)
			{
				postfix.method = methodInfo2;
			}
			if (transpiler != null)
			{
				transpiler.method = methodInfo3;
			}
			if (finalizer != null)
			{
				finalizer.method = methodInfo4;
			}
			if ((object)methodInfo != null)
			{
				if (!methodInfo.IsStatic)
				{
					throw new ArgumentException("Patch method " + Extensions.GetID((MethodBase)methodInfo, (string)null, (string)null, true, false, false) + " must be static");
				}
				List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod(methodInfo);
				containerAttributes.Merge(HarmonyMethod.Merge(fromMethod)).CopyTo(prefix);
			}
			if ((object)methodInfo2 != null)
			{
				if (!methodInfo2.IsStatic)
				{
					throw new ArgumentException("Patch method " + Extensions.GetID((MethodBase)methodInfo2, (string)null, (string)null, true, false, false) + " must be static");
				}
				List<HarmonyMethod> fromMethod2 = HarmonyMethodExtensions.GetFromMethod(methodInfo2);
				containerAttributes.Merge(HarmonyMethod.Merge(fromMethod2)).CopyTo(postfix);
			}
			if ((object)methodInfo3 != null)
			{
				if (!methodInfo3.IsStatic)
				{
					throw new ArgumentException("Patch method " + Extensions.GetID((MethodBase)methodInfo3, (string)null, (string)null, true, false, false) + " must be static");
				}
				List<HarmonyMethod> fromMethod3 = HarmonyMethodExtensions.GetFromMethod(methodInfo3);
				containerAttributes.Merge(HarmonyMethod.Merge(fromMethod3)).CopyTo(transpiler);
			}
			if ((object)methodInfo4 != null)
			{
				if (!methodInfo4.IsStatic)
				{
					throw new ArgumentException("Patch method " + Extensions.GetID((MethodBase)methodInfo4, (string)null, (string)null, true, false, false) + " must be static");
				}
				List<HarmonyMethod> fromMethod4 = HarmonyMethodExtensions.GetFromMethod(methodInfo4);
				containerAttributes.Merge(HarmonyMethod.Merge(fromMethod4)).CopyTo(finalizer);
			}
		}

		internal static MethodBase GetOriginalMethod(HarmonyMethod attribute)
		{
			if (attribute == null)
			{
				throw new ArgumentNullException("attribute");
			}
			if ((object)attribute.declaringType == null)
			{
				return MakeFailure("declaringType cannot be null");
			}
			switch (attribute.methodType)
			{
			case MethodType.Normal:
			{
				if (string.IsNullOrEmpty(attribute.methodName))
				{
					return MakeFailure("methodName can't be empty");
				}
				if (attribute.methodName == ".ctor")
				{
					Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.Constructor should be used instead of setting methodName to .ctor");
					goto case MethodType.Constructor;
				}
				if (attribute.methodName == ".cctor")
				{
					Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.StaticConstructor should be used instead of setting methodName to .cctor");
					goto case MethodType.StaticConstructor;
				}
				if (attribute.methodName.StartsWith("get_") || attribute.methodName.StartsWith("set_"))
				{
					Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - MethodType.Getter and MethodType.Setter should be used instead adding get_ and set_ to property names");
				}
				MethodInfo methodInfo = AccessTools.DeclaredMethod(attribute.declaringType, attribute.methodName, attribute.argumentTypes);
				if ((object)methodInfo != null)
				{
					return methodInfo;
				}
				methodInfo = AccessTools.Method(attribute.declaringType, attribute.methodName, attribute.argumentTypes);
				if ((object)methodInfo != null)
				{
					string text = GetPatchName();
					object[] obj = new object[4] { attribute.methodName, null, null, null };
					Type[] argumentTypes = attribute.argumentTypes;
					obj[1] = ((argumentTypes != null) ? argumentTypes.Length : 0);
					obj[2] = attribute.declaringType.FullDescription();
					obj[3] = methodInfo.DeclaringType.FullDescription();
					Logger.LogText(Logger.LogChannel.Warn, text + string.Format(" - Could not find method {0} with {1} parameters in type {2}, but it was found in base class of this type {3}", obj));
					return methodInfo;
				}
				return MakeFailure("Could not find method " + attribute.methodName + " with " + attribute.argumentTypes.Description() + " parameters in type " + attribute.declaringType.FullDescription());
			}
			case MethodType.Getter:
			{
				if (string.IsNullOrEmpty(attribute.methodName))
				{
					return MakeFailure("methodName can't be empty");
				}
				PropertyInfo propertyInfo2 = AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName);
				if ((object)propertyInfo2 != null)
				{
					MethodInfo getMethod = propertyInfo2.GetGetMethod(nonPublic: true);
					if ((object)getMethod == null)
					{
						return MakeFailure("Property " + attribute.methodName + " does not have a Getter");
					}
					return getMethod;
				}
				propertyInfo2 = AccessTools.Property(attribute.declaringType, attribute.methodName);
				if ((object)propertyInfo2 != null)
				{
					Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - Could not find property " + attribute.methodName + " in type " + attribute.declaringType.FullDescription() + ", but it was found in base class of this type: " + propertyInfo2.DeclaringType.FullDescription());
					MethodInfo getMethod2 = propertyInfo2.GetGetMethod(nonPublic: true);
					if ((object)getMethod2 == null)
					{
						return MakeFailure("Property " + attribute.methodName + " does not have a Getter");
					}
					return getMethod2;
				}
				return MakeFailure("Could not find property " + attribute.methodName + " in type " + attribute.declaringType.FullDescription());
			}
			case MethodType.Setter:
			{
				if (string.IsNullOrEmpty(attribute.methodName))
				{
					return MakeFailure("methodName can't be empty");
				}
				PropertyInfo propertyInfo = AccessTools.DeclaredProperty(attribute.declaringType, attribute.methodName);
				if ((object)propertyInfo != null)
				{
					MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
					if ((object)setMethod == null)
					{
						return MakeFailure("Property " + attribute.methodName + " does not have a Setter");
					}
					return setMethod;
				}
				propertyInfo = AccessTools.Property(attribute.declaringType, attribute.methodName);
				if ((object)propertyInfo != null)
				{
					Logger.LogText(Logger.LogChannel.Warn, GetPatchName() + " - Could not find property " + attribute.methodName + " in type " + attribute.declaringType.FullDescription() + ", but it was found in base class of this type: " + propertyInfo.DeclaringType.FullDescription());
					MethodInfo setMethod2 = propertyInfo.GetSetMethod(nonPublic: true);
					if ((object)setMethod2 == null)
					{
						return MakeFailure("Property " + attribute.methodName + " does not have a Setter");
					}
					return setMethod2;
				}
				return MakeFailure("Could not find property " + attribute.methodName + " in type " + attribute.declaringType.FullDescription());
			}
			case MethodType.Constructor:
			{
				ConstructorInfo constructorInfo2 = AccessTools.DeclaredConstructor(attribute.declaringType, attribute.argumentTypes);
				if ((object)constructorInfo2 != null)
				{
					return constructorInfo2;
				}
				return MakeFailure("Could not find constructor with " + attribute.argumentTypes.Description() + " parameters in type " + attribute.declaringType.FullDescription());
			}
			case MethodType.StaticConstructor:
			{
				ConstructorInfo constructorInfo = AccessTools.GetDeclaredConstructors(attribute.declaringType).FirstOrDefault((ConstructorInfo c) => c.IsStatic);
				if ((object)constructorInfo != null)
				{
					return constructorInfo;
				}
				return MakeFailure("Could not find static constructor in type " + attribute.declaringType.FullDescription());
			}
			default:
				throw new ArgumentOutOfRangeException("methodType", attribute.methodType, "Unknown method type");
			}
			string GetPatchName()
			{
				return attribute.method?.FullDescription() ?? "Unknown patch";
			}
			MethodBase MakeFailure(string reason)
			{
				Logger.Log(Logger.LogChannel.Error, () => "Failed to process patch " + GetPatchName() + " - " + reason);
				return null;
			}
		}

		private T RunMethod<S, T>(T defaultIfNotExisting, params object[] parameters)
		{
			if ((object)container == null)
			{
				return defaultIfNotExisting;
			}
			string name = typeof(S).Name.Replace("Harmony", "");
			MethodInfo patchMethod = GetPatchMethod<S>(container, name);
			if ((object)patchMethod != null)
			{
				if (typeof(T).IsAssignableFrom(patchMethod.ReturnType))
				{
					object[] emptyTypes = Type.EmptyTypes;
					return (T)patchMethod.Invoke(null, emptyTypes);
				}
				object[] inputs = (parameters ?? new object[0]).Union(new object[1] { instance }).ToArray();
				object[] parameters2 = AccessTools.ActualParameters(patchMethod, inputs);
				patchMethod.Invoke(null, parameters2);
				return defaultIfNotExisting;
			}
			return defaultIfNotExisting;
		}

		private void RunMethod<S>(params object[] parameters)
		{
			if ((object)container != null)
			{
				string name = typeof(S).Name.Replace("Harmony", "");
				MethodInfo patchMethod = GetPatchMethod<S>(container, name);
				if ((object)patchMethod != null)
				{
					object[] inputs = (parameters ?? new object[0]).Union(new object[1] { instance }).ToArray();
					object[] parameters2 = AccessTools.ActualParameters(patchMethod, inputs);
					patchMethod.Invoke(null, parameters2);
				}
			}
		}

		private MethodInfo GetPatchMethod<T>(Type patchType, string name)
		{
			string attributeType = typeof(T).FullName;
			MethodInfo methodInfo = patchType.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.GetCustomAttributes(inherit: true).Any((object a) => a.GetType().FullName == attributeType));
			if ((object)methodInfo == null)
			{
				methodInfo = patchType.GetMethod(name, AccessTools.all);
			}
			return methodInfo;
		}

		private void GetPatches(Type patchType, out MethodInfo prefix, out MethodInfo postfix, out MethodInfo transpiler, out MethodInfo finalizer)
		{
			prefix = GetPatchMethod<HarmonyPrefix>(patchType, "Prefix");
			postfix = GetPatchMethod<HarmonyPostfix>(patchType, "Postfix");
			transpiler = GetPatchMethod<HarmonyTranspiler>(patchType, "Transpiler");
			finalizer = GetPatchMethod<HarmonyFinalizer>(patchType, "Finalizer");
		}
	}
	public class ReversePatcher
	{
		private readonly Harmony instance;

		private readonly MethodBase original;

		private readonly MethodInfo standin;

		private readonly ILHook ilHook;

		public ReversePatcher(Harmony instance, MethodBase original, MethodInfo standin)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			this.instance = instance;
			this.original = original;
			this.standin = standin;
			ilHook = new ILHook((MethodBase)standin, new Manipulator(ApplyReversePatch), new ILHookConfig
			{
				ManualApply = true
			});
		}

		private void ApplyReversePatch(ILContext ctx)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			DynamicMethodDefinition val = new DynamicMethodDefinition(original);
			ILManipulator iLManipulator = new ILManipulator(val.Definition.Body);
			ctx.Body.Variables.Clear();
			Enumerator<VariableDefinition> enumerator = val.Definition.Body.Variables.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					VariableDefinition current = enumerator.Current;
					ctx.Body.Variables.Add(new VariableDefinition(ctx.Module.ImportReference(((VariableReference)current).VariableType)));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			MethodInfo transpiler = GetTranspiler(standin);
			if ((object)transpiler != null)
			{
				iLManipulator.AddTranspiler(transpiler);
			}
			iLManipulator.WriteTo(ctx.Body, standin);
			ctx.IL.Emit(OpCodes.Ret);
		}

		public void Patch(HarmonyReversePatchType type = HarmonyReversePatchType.Original)
		{
			if ((object)original == null)
			{
				throw new NullReferenceException("Null method for " + instance.Id);
			}
			ilHook.Apply();
		}

		private MethodInfo GetTranspiler(MethodInfo method)
		{
			string methodName = method.Name;
			List<MethodInfo> declaredMethods = AccessTools.GetDeclaredMethods(method.DeclaringType);
			Type ici = typeof(IEnumerable<CodeInstruction>);
			return declaredMethods.FirstOrDefault((MethodInfo m) => (object)m.ReturnType == ici && m.Name.StartsWith("<" + methodName + ">"));
		}
	}
	public class CodeMatch
	{
		public string name;

		public List<OpCode> opcodes = new List<OpCode>();

		public List<object> operands = new List<object>();

		public List<Label> labels = new List<Label>();

		public List<ExceptionBlock> blocks = new List<ExceptionBlock>();

		public List<int> jumpsFrom = new List<int>();

		public List<int> jumpsTo = new List<int>();

		public Func<CodeInstruction, bool> predicate;

		public CodeMatch(OpCode? opcode = null, object operand = null, string name = null)
		{
			if (opcode.HasValue)
			{
				OpCode valueOrDefault = opcode.GetValueOrDefault();
				opcodes.Add(valueOrDefault);
			}
			if (operand != null)
			{
				operands.Add(operand);
			}
			this.name = name;
		}

		public CodeMatch(CodeInstruction instruction, string name = null)
			: this(instruction.opcode, instruction.operand, name)
		{
		}

		public CodeMatch(Func<CodeInstruction, bool> predicate, string name = null)
		{
			this.predicate = predicate;
			this.name = name;
		}

		internal bool Matches(List<CodeInstruction> codes, CodeInstruction instruction)
		{
			if (predicate != null)
			{
				return predicate(instruction);
			}
			if (opcodes.Count > 0 && !opcodes.Contains(instruction.opcode))
			{
				return false;
			}
			if (operands.Count > 0 && !operands.Contains(instruction.operand))
			{
				return false;
			}
			if (labels.Count > 0 && !labels.Intersect(instruction.labels).Any())
			{
				return false;
			}
			if (blocks.Count > 0 && !blocks.Intersect(instruction.blocks).Any())
			{
				return false;
			}
			if (jumpsFrom.Count > 0 && !jumpsFrom.Select((int index) => codes[index].operand).OfType<Label>().Intersect(instruction.labels)
				.Any())
			{
				return false;
			}
			if (jumpsTo.Count > 0)
			{
				object operand = instruction.operand;
				if (operand == null || (object)operand.GetType() != typeof(Label))
				{
					return false;
				}
				Label label = (Label)operand;
				IEnumerable<int> second = from idx in Enumerable.Range(0, codes.Count)
					where codes[idx].labels.Contains(label)
					select idx;
				if (!jumpsTo.Intersect(second).Any())
				{
					return false;
				}
			}
			return true;
		}

		public override string ToString()
		{
			string text = "[";
			if (name != null)
			{
				text = text + name + ": ";
			}
			if (opcodes.Count > 0)
			{
				text = text + "opcodes=" + opcodes.Join() + " ";
			}
			if (operands.Count > 0)
			{
				text = text + "operands=" + operands.Join() + " ";
			}
			if (labels.Count > 0)
			{
				text = text + "labels=" + labels.Join() + " ";
			}
			if (blocks.Count > 0)
			{
				text = text + "blocks=" + blocks.Join() + " ";
			}
			if (jumpsFrom.Count > 0)
			{
				text = text + "jumpsFrom=" + jumpsFrom.Join() + " ";
			}
			if (jumpsTo.Count > 0)
			{
				text = text + "jumpsTo=" + jumpsTo.Join() + " ";
			}
			if (predicate != null)
			{
				text += "predicate=yes ";
			}
			return text.TrimEnd(new char[0]) + "]";
		}
	}
	public class CodeMatcher
	{
		private readonly ILGenerator generator;

		private readonly List<CodeInstruction> codes = new List<CodeInstruction>();

		private Dictionary<string, CodeInstruction> lastMatches = new Dictionary<string, CodeInstruction>();

		private string lastError;

		private bool lastUseEnd;

		private CodeMatch[] lastCodeMatches;

		public int Pos { get; private set; } = -1;


		public int Length => codes.Count;

		public bool IsValid
		{
			get
			{
				if (Pos >= 0)
				{
					return Pos < Length;
				}
				return false;
			}
		}

		public bool IsInvalid
		{
			get
			{
				if (Pos >= 0)
				{
					return Pos >= Length;
				}
				return true;
			}
		}

		public int Remaining => Length - Math.Max(0, Pos);

		public ref OpCode Opcode => ref codes[Pos].opcode;

		public ref object Operand => ref codes[Pos].operand;

		public ref List<Label> Labels => ref codes[Pos].labels;

		public ref List<ExceptionBlock> Blocks => ref codes[Pos].blocks;

		public CodeInstruction Instruction => codes[Pos];

		private void FixStart()
		{
			Pos = Math.Max(0, Pos);
		}

		private void SetOutOfBounds(int direction)
		{
			Pos = ((direction > 0) ? Length : (-1));
		}

		public CodeMatcher()
		{
		}

		public CodeMatcher(IEnumerable<CodeInstruction> instructions, ILGenerator generator = null)
		{
			this.generator = generator;
			codes = instructions.Select((CodeInstruction c) => new CodeInstruction(c)).ToList();
		}

		public CodeMatcher Clone()
		{
			return new CodeMatcher(codes, generator)
			{
				Pos = Pos,
				lastMatches = lastMatches,
				lastError = lastError,
				lastUseEnd = lastUseEnd,
				lastCodeMatches = lastCodeMatches
			};
		}

		public CodeInstruction InstructionAt(int offset)
		{
			return codes[Pos + offset];
		}

		public List<CodeInstruction> Instructions()
		{
			return codes;
		}

		public IEnumerable<CodeInstruction> InstructionEnumeration()
		{
			return codes.AsEnumerable();
		}

		public List<CodeInstruction> Instructions(int count)
		{
			return (from c in codes.GetRange(Pos, count)
				select new CodeInstruction(c)).ToList();
		}

		public List<CodeInstruction> InstructionsInRange(int start, int end)
		{
			List<CodeInstruction> list = codes;
			if (start > end)
			{
				int num = start;
				start = end;
				end = num;
			}
			return (from c in list.GetRange(start, end - start + 1)
				select new CodeInstruction(c)).ToList();
		}

		public List<CodeInstruction> InstructionsWithOffsets(int startOffset, int endOffset)
		{
			return InstructionsInRange(Pos + startOffset, Pos + endOffset);
		}

		public List<Label> DistinctLabels(IEnumerable<CodeInstruction> instructions)
		{
			return instructions.SelectMany((CodeInstruction instruction) => instruction.labels).Distinct().ToList();
		}

		public bool ReportFailure(MethodBase method, Action<string> logger)
		{
			if (IsValid)
			{
				return false;
			}
			string arg = lastError ?? "Unexpected code";
			logger($"{arg} in {method}");
			return true;
		}

		public CodeMatcher SetInstruction(CodeInstruction instruction)
		{
			codes[Pos] = instruction;
			return this;
		}

		public CodeMatcher SetInstructionAndAdvance(CodeInstruction instruction)
		{
			SetInstruction(instruction);
			Pos++;
			return this;
		}

		public CodeMatcher Set(OpCode opcode, object operand)
		{
			Opcode = opcode;
			Operand = operand;
			return this;
		}

		public CodeMatcher SetAndAdvance(OpCode opcode, object operand)
		{
			Set(opcode, operand);
			Pos++;
			return this;
		}

		public CodeMatcher SetOpcodeAndAdvance(OpCode opcode)
		{
			Opcode = opcode;
			Pos++;
			return this;
		}

		public CodeMatcher SetOperandAndAdvance(object operand)
		{
			Operand = operand;
			Pos++;
			return this;
		}

		public CodeMatcher CreateLabel(out Label label)
		{
			label = generator.DefineLabel();
			Labels.Add(label);
			return this;
		}

		public CodeMatcher CreateLabelAt(int position, out Label label)
		{
			label = generator.DefineLabel();
			AddLabelsAt(position, new Label[1] { label });
			return this;
		}

		public CodeMatcher AddLabels(IEnumerable<Label> labels)
		{
			Labels.AddRange(labels);
			return this;
		}

		public CodeMatcher AddLabelsAt(int position, IEnumerable<Label> labels)
		{
			codes[position].labels.AddRange(labels);
			return this;
		}

		public CodeMatcher SetJumpTo(OpCode opcode, int destination, out Label label)
		{
			CreateLabelAt(destination, out label);
			Set(opcode, label);
			return this;
		}

		public CodeMatcher Insert(params CodeInstruction[] instructions)
		{
			codes.InsertRange(Pos, instructions);
			return this;
		}

		public CodeMatcher Insert(IEnumerable<CodeInstruction> instructions)
		{
			codes.InsertRange(Pos, instructions);
			return this;
		}

		public CodeMatcher InsertBranch(OpCode opcode, int destination)
		{
			CreateLabelAt(destination, out var label);
			codes.Insert(Pos, new CodeInstruction(opcode, label));
			return this;
		}

		public CodeMatcher InsertAndAdvance(params CodeInstruction[] instructions)
		{
			foreach (CodeInstruction codeInstruction in instructions)
			{
				Insert(codeInstruction);
				Pos++;
			}
			return this;
		}

		public CodeMatcher InsertAndAdvance(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				InsertAndAdvance(instruction);
			}
			return this;
		}

		public CodeMatcher InsertBranchAndAdvance(OpCode opcode, int destination)
		{
			InsertBranch(opcode, destination);
			Pos++;
			return this;
		}

		public CodeMatcher RemoveInstruction()
		{
			codes.RemoveAt(Pos);
			return this;
		}

		public CodeMatcher RemoveInstructions(int count)
		{
			codes.RemoveRange(Pos, count);
			return this;
		}

		public CodeMatcher RemoveInstructionsInRange(int start, int end)
		{
			if (start > end)
			{
				int num = start;
				start = end;
				end = num;
			}
			codes.RemoveRange(start, end - start + 1);
			return this;
		}

		public CodeMatcher RemoveInstructionsWithOffsets(int startOffset, int endOffset)
		{
			RemoveInstructionsInRange(Pos + startOffset, Pos + endOffset);
			return this;
		}

		public CodeMatcher Advance(int offset)
		{
			Pos += offset;
			if (!IsValid)
			{
				SetOutOfBounds(offset);
			}
			return this;
		}

		public CodeMatcher Start()
		{
			Pos = 0;
			return this;
		}

		public CodeMatcher End()
		{
			Pos = Length - 1;
			return this;
		}

		public CodeMatcher SearchForward(Func<CodeInstruction, bool> predicate)
		{
			return Search(predicate, 1);
		}

		public CodeMatcher SearchBack(Func<CodeInstruction, bool> predicate)
		{
			return Search(predicate, -1);
		}

		private CodeMatcher Search(Func<CodeInstruction, bool> predicate, int direction)
		{
			FixStart();
			while (IsValid && !predicate(Instruction))
			{
				Pos += direction;
			}
			lastError = (IsInvalid ? $"Cannot find {predicate}" : null);
			return this;
		}

		public CodeMatcher MatchForward(bool useEnd, params CodeMatch[] matches)
		{
			return Match(matches, 1, useEnd);
		}

		public CodeMatcher MatchBack(bool useEnd, params CodeMatch[] matches)
		{
			return Match(matches, -1, useEnd);
		}

		private CodeMatcher Match(CodeMatch[] matches, int direction, bool useEnd)
		{
			FixStart();
			while (IsValid)
			{
				lastUseEnd = useEnd;
				lastCodeMatches = matches;
				if (MatchSequence(Pos, matches))
				{
					if (useEnd)
					{
						Pos += matches.Count() - 1;
					}
					break;
				}
				Pos += direction;
			}
			lastError = (IsInvalid ? ("Cannot find " + matches.Join()) : null);
			return this;
		}

		public CodeMatcher Repeat(Action<CodeMatcher> matchAction, Action<string> notFoundAction = null)
		{
			int num = 0;
			if (lastCodeMatches == null)
			{
				throw new InvalidOperationException("No previous Match operation - cannot repeat");
			}
			while (IsValid)
			{
				matchAction(this);
				MatchForward(lastUseEnd, lastCodeMatches);
				num++;
			}
			lastCodeMatches = null;
			if (num == 0)
			{
				notFoundAction?.Invoke(lastError);
			}
			return this;
		}

		public CodeInstruction NamedMatch(string name)
		{
			return lastMatches[name];
		}

		private bool MatchSequence(int start, CodeMatch[] matches)
		{
			if (start < 0)
			{
				return false;
			}
			lastMatches = new Dictionary<string, CodeInstruction>();
			foreach (CodeMatch codeMatch in matches)
			{
				if (start >= Length || !codeMatch.Matches(codes, codes[start]))
				{
					return false;
				}
				if (codeMatch.name != null)
				{
					lastMatches.Add(codeMatch.name, codes[start]);
				}
				start++;
			}
			return true;
		}
	}
	public static class CodeInstructionExtensions
	{
		private static readonly HashSet<OpCode> LoadVarCodes = new HashSet<OpCode>
		{
			OpCodes.Ldloc_0,
			OpCodes.Ldloc_1,
			OpCodes.Ldloc_2,
			OpCodes.Ldloc_3,
			OpCodes.Ldloc,
			OpCodes.Ldloca,
			OpCodes.Ldloc_S,
			OpCodes.Ldloca_S
		};

		private static readonly HashSet<OpCode> StoreVarCodes = new HashSet<OpCode>
		{
			OpCodes.Stloc_0,
			OpCodes.Stloc_1,
			OpCodes.Stloc_2,
			OpCodes.Stloc_3,
			OpCodes.Stloc,
			OpCodes.Stloc_S
		};

		private static readonly HashSet<OpCode> BranchCodes = new HashSet<OpCode>
		{
			OpCodes.Br_S,
			OpCodes.Brfalse_S,
			OpCodes.Brtrue_S,
			OpCodes.Beq_S,
			OpCodes.Bge_S,
			OpCodes.Bgt_S,
			OpCodes.Ble_S,
			OpCodes.Blt_S,
			OpCodes.Bne_Un_S,
			OpCodes.Bge_Un_S,
			OpCodes.Bgt_Un_S,
			OpCodes.Ble_Un_S,
			OpCodes.Blt_Un_S,
			OpCodes.Br,
			OpCodes.Brfalse,
			OpCodes.Brtrue,
			OpCodes.Beq,
			OpCodes.Bge,
			OpCodes.Bgt,
			OpCodes.Ble,
			OpCodes.Blt,
			OpCodes.Bne_Un,
			OpCodes.Bge_Un,
			OpCodes.Bgt_Un,
			OpCodes.Ble_Un,
			OpCodes.Blt_Un
		};

		private static readonly HashSet<OpCode> ConstantLoadingCodes = new HashSet<OpCode>
		{
			OpCodes.Ldc_I4_M1,
			OpCodes.Ldc_I4_0,
			OpCodes.Ldc_I4_1,
			OpCodes.Ldc_I4_2,
			OpCodes.Ldc_I4_3,
			OpCodes.Ldc_I4_4,
			OpCodes.Ldc_I4_5,
			OpCodes.Ldc_I4_6,
			OpCodes.Ldc_I4_7,
			OpCodes.Ldc_I4_8,
			OpCodes.Ldc_I4,
			OpCodes.Ldc_I4_S,
			OpCodes.Ldc_I8,
			OpCodes.Ldc_R4,
			OpCodes.Ldc_R8
		};

		public static bool OperandIs(this CodeInstruction code, object value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (code.operand == null)
			{
				return false;
			}
			Type type = value.GetType();
			Type type2 = code.operand.GetType();
			if (AccessTools.IsInteger(type) && AccessTools.IsNumber(type2))
			{
				return Convert.ToInt64(code.operand) == Convert.ToInt64(value);
			}
			if (AccessTools.IsFloatingPoint(type) && AccessTools.IsNumber(type2))
			{
				return Convert.ToDouble(code.operand) == Convert.ToDouble(value);
			}
			return object.Equals(code.operand, value);
		}

		public static bool Is(this CodeInstruction code, OpCode opcode, object operand)
		{
			if (code.opcode == opcode)
			{
				return code.OperandIs(operand);
			}
			return false;
		}

		public static bool IsLdarg(this CodeInstruction code, int? n = null)
		{
			if ((!n.HasValue || n.Value == 0) && code.opcode == OpCodes.Ldarg_0)
			{
				return true;
			}
			if ((!n.HasValue || n.Value == 1) && code.opcode == OpCodes.Ldarg_1)
			{
				return true;
			}
			if ((!n.HasValue || n.Value == 2) && code.opcode == OpCodes.Ldarg_2)
			{
				return true;
			}
			if ((!n.HasValue || n.Value == 3) && code.opcode == OpCodes.Ldarg_3)
			{
				return true;
			}
			if (code.opcode == OpCodes.Ldarg && (!n.HasValue || n.Value == Convert.ToInt32(code.operand)))
			{
				return true;
			}
			if (code.opcode == OpCodes.Ldarg_S && (!n.HasValue || n.Value == Convert.ToInt32(code.operand)))
			{
				return true;
			}
			return false;
		}

		public static bool IsLdarga(this CodeInstruction code, int? n = null)
		{
			if (code.opcode != OpCodes.Ldarga && code.opcode != OpCodes.Ldarga_S)
			{
				return false;
			}
			if (n.HasValue)
			{
				return n.Value == Convert.ToInt32(code.operand);
			}
			return true;
		}

		public static bool IsStarg(this CodeInstruction code, int? n = null)
		{
			if (code.opcode != OpCodes.Starg && code.opcode != OpCodes.Starg_S)
			{
				return false;
			}
			if (n.HasValue)
			{
				return n.Value == Convert.ToInt32(code.operand);
			}
			return true;
		}

		public static bool IsLdloc(this CodeInstruction code, LocalBuilder variable = null)
		{
			if (!LoadVarCodes.Contains(code.opcode))
			{
				return false;
			}
			if (variable != null)
			{
				return object.Equals(variable, code.operand);
			}
			return true;
		}

		public static bool IsStloc(this CodeInstruction code, LocalBuilder variable = null)
		{
			if (!StoreVarCodes.Contains(code.opcode))
			{
				return false;
			}
			if (variable != null)
			{
				return object.Equals(variable, code.operand);
			}
			return true;
		}

		public static bool Branches(this CodeInstruction code, out Label? label)
		{
			if (BranchCodes.Contains(code.opcode))
			{
				label = (Label)code.operand;
				return true;
			}
			label = null;
			return false;
		}

		public static bool Calls(this CodeInstruction code, MethodInfo method)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			if (code.opcode != OpCodes.Call && code.opcode != OpCodes.Callvirt)
			{
				return false;
			}
			return object.Equals(code.operand, method);
		}

		public static bool LoadsConstant(this CodeInstruction code)
		{
			return ConstantLoadingCodes.Contains(code.opcode);
		}

		public static bool LoadsConstant(this CodeInstruction code, long number)
		{
			OpCode opcode = code.opcode;
			if (number == -1 && opcode == OpCodes.Ldc_I4_M1)
			{
				return true;
			}
			if (number == 0L && opcode == OpCodes.Ldc_I4_0)
			{
				return true;
			}
			if (number == 1 && opcode == OpCodes.Ldc_I4_1)
			{
				return true;
			}
			if (number == 2 && opcode == OpCodes.Ldc_I4_2)
			{
				return true;
			}
			if (number == 3 && opcode == OpCodes.Ldc_I4_3)
			{
				return true;
			}
			if (number == 4 && opcode == OpCodes.Ldc_I4_4)
			{
				return true;
			}
			if (number == 5 && opcode == OpCodes.Ldc_I4_5)
			{
				return true;
			}
			if (number == 6 && opcode == OpCodes.Ldc_I4_6)
			{
				return true;
			}
			if (number == 7 && opcode == OpCodes.Ldc_I4_7)
			{
				return true;
			}
			if (number == 8 && opcode == OpCodes.Ldc_I4_8)
			{
				return true;
			}
			if (opcode != OpCodes.Ldc_I4 && opcode != OpCodes.Ldc_I4_S && opcode != OpCodes.Ldc_I8)
			{
				return false;
			}
			return Convert.ToInt64(code.operand) == number;
		}

		public static bool LoadsConstant(this CodeInstruction code, double number)
		{
			if (code.opcode != OpCodes.Ldc_R4 && code.opcode != OpCodes.Ldc_R8)
			{
				return false;
			}
			return Convert.ToDouble(code.operand) == number;
		}

		public static bool LoadsConstant(this CodeInstruction code, Enum e)
		{
			return code.LoadsConstant(Convert.ToInt64(e));
		}

		public static bool LoadsField(this CodeInstruction code, FieldInfo field, bool byAddress = false)
		{
			if ((object)field == null)
			{
				throw new ArgumentNullException("field");
			}
			OpCode opCode = (field.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld);
			if (!byAddress && code.opcode == opCode && object.Equals(code.operand, field))
			{
				return true;
			}
			OpCode opCode2 = (field.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda);
			if (byAddress && code.opcode == opCode2 && object.Equals(code.operand, field))
			{
				return true;
			}
			return false;
		}

		public static bool StoresField(this CodeInstruction code, FieldInfo field)
		{
			if ((object)field == null)
			{
				throw new ArgumentNullException("field");
			}
			OpCode opCode = (field.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld);
			if (code.opcode == opCode)
			{
				return object.Equals(code.operand, field);
			}
			return false;
		}

		public static CodeInstruction WithLabels(this CodeInstruction code, params Label[] labels)
		{
			code.labels.AddRange(labels);
			return code;
		}

		public static CodeInstruction WithLabels(this CodeInstruction code, IEnumerable<Label> labels)
		{
			code.labels.AddRange(labels);
			return code;
		}

		public static List<Label> ExtractLabels(this CodeInstruction code)
		{
			List<Label> result = new List<Label>(code.labels);
			code.labels.Clear();
			return result;
		}

		public static CodeInstruction MoveLabelsTo(this CodeInstruction code, CodeInstruction other)
		{
			other.WithLabels(code.ExtractLabels());
			return code;
		}

		public static CodeInstruction MoveLabelsFrom(this CodeInstruction code, CodeInstruction other)
		{
			return code.WithLabels(other.ExtractLabels());
		}

		public static CodeInstruction WithBlocks(this CodeInstruction code, params ExceptionBlock[] blocks)
		{
			code.blocks.AddRange(blocks);
			return code;
		}

		public static CodeInstruction WithBlocks(this CodeInstruction code, IEnumerable<ExceptionBlock> blocks)
		{
			code.blocks.AddRange(blocks);
			return code;
		}

		public static List<ExceptionBlock> ExtractBlocks(this CodeInstruction code)
		{
			List<ExceptionBlock> result = new List<ExceptionBlock>(code.blocks);
			code.blocks.Clear();
			return result;
		}

		public static CodeInstruction MoveBlocksTo(this CodeInstruction code, CodeInstruction other)
		{
			other.WithBlocks(code.ExtractBlocks());
			return code;
		}

		public static CodeInstruction MoveBlocksFrom(this CodeInstruction code, CodeInstruction other)
		{
			return code.WithBlocks(other.ExtractBlocks());
		}
	}
	public static class CollectionExtensions
	{
		public static void Do<T>(this IEnumerable<T> sequence, Action<T> action)
		{
			if (sequence != null)
			{
				IEnumerator<T> enumerator = sequence.GetEnumerator();
				while (enumerator.MoveNext())
				{
					action(enumerator.Current);
				}
			}
		}

		public static void DoIf<T>(this IEnumerable<T> sequence, Func<T, bool> condition, Action<T> action)
		{
			sequence.Where(condition).Do(action);
		}

		public static IEnumerable<T> AddItem<T>(this IEnumerable<T> sequence, T item)
		{
			return (sequence ?? Enumerable.Empty<T>()).Concat(new T[1] { item });
		}

		public static T[] AddToArray<T>(this T[] sequence, T item)
		{
			return sequence.AddItem(item).ToArray();
		}

		public static T[] AddRangeToArray<T>(this T[] sequence, T[] items)
		{
			return (sequence ?? Enumerable.Empty<T>()).Concat(items).ToArray();
		}
	}
	public static class GeneralExtensions
	{
		public static string Join<T>(this IEnumerable<T> enumeration, Func<T, string> converter = null, string delimiter = ", ")
		{
			if (converter == null)
			{
				converter = (T t) => t.ToString();
			}
			return enumeration.Aggregate("", (string prev, T curr) => prev + ((prev != "") ? delimiter : "") + converter(curr));
		}

		public static string Description(this Type[] parameters)
		{
			if (parameters == null)
			{
				return "NULL";
			}
			return "(" + parameters.Join((Type p) => p.FullDescription()) + ")";
		}

		public static string FullDescription(this Type type)
		{
			if ((object)type == null)
			{
				return "null";
			}
			string text = type.Namespace;
			if (!string.IsNullOrEmpty(text))
			{
				text += ".";
			}
			string text2 = text + type.Name;
			if (type.IsGenericType)
			{
				text2 += "<";
				Type[] genericArguments = type.GetGenericArguments();
				for (int i = 0; i < genericArguments.Length; i++)
				{
					if (!text2.EndsWith("<", StringComparison.Ordinal))
					{
						text2 += ", ";
					}
					text2 += genericArguments[i].FullDescription();
				}
				text2 += ">";
			}
			return text2;
		}

		public static string FullDescription(this MethodBase method)
		{
			if ((object)method == null)
			{
				return "null";
			}
			Type[] parameters = (from p in method.GetParameters()
				select p.ParameterType).ToArray();
			Type returnedType = AccessTools.GetReturnedType(method);
			return returnedType.FullDescription() + " " + method.DeclaringType.FullDescription() + "." + method.Name + parameters.Description();
		}

		public static Type[] Types(this ParameterInfo[] pinfo)
		{
			return pinfo.Select((ParameterInfo pi) => pi.ParameterType).ToArray();
		}

		public static T GetValueSafe<S, T>(this Dictionary<S, T> dictionary, S key)
		{
			if (dictionary.TryGetValue(key, out var value))
			{
				return value;
			}
			return default(T);
		}

		public static T GetTypedValue<T>(this Dictionary<string, object> dictionary, string key)
		{
			if (dictionary.TryGetValue(key, out var value) && value is T)
			{
				return (T)value;
			}
			return default(T);
		}
	}
	public static class SymbolExtensions
	{
		public static MethodInfo GetMethodInfo(Expression<Action> expression)
		{
			return GetMethodInfo((LambdaExpression)expression);
		}

		public static MethodInfo GetMethodInfo<T>(Expression<Action<T>> expression)
		{
			return GetMethodInfo((LambdaExpression)expression);
		}

		public static MethodInfo GetMethodInfo<T, TResult>(Expression<Func<T, TResult>> expression)
		{
			return GetMethodInfo((LambdaExpression)expression);
		}

		public static MethodInfo GetMethodInfo(LambdaExpression expression)
		{
			return ((expression.Body as MethodCallExpression) ?? throw new ArgumentException("Invalid Expression. Expression should consist of a Method call only.")).Method ?? throw new MemberNotFoundException($"Cannot find method for expression {expression}");
		}
	}
	[Obsolete("Use HarmonyFileLog instead", true)]
	public static class FileLog
	{
		public static string logPath;

		public static char indentChar;

		public static int indentLevel;

		private static List<string> buffer;

		static FileLog()
		{
			indentChar = '\t';
			buffer = new List<string>();
			logPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}{Path.DirectorySeparatorChar}harmony.log.txt";
		}

		private static string IndentString()
		{
			return new string(indentChar, indentLevel);
		}

		public static void ChangeIndent(int delta)
		{
			indentLevel = Math.Max(0, indentLevel + delta);
		}

		public static void LogBuffered(string str)
		{
			lock (logPath)
			{
				buffer.Add(IndentString() + str);
			}
		}

		public static void LogBuffered(List<string> strings)
		{
			lock (logPath)
			{
				buffer.AddRange(strings);
			}
		}

		public static List<string> GetBuffer(bool clear)
		{
			lock (logPath)
			{
				List<string> result = buffer;
				if (clear)
				{
					buffer = new List<string>();
				}
				return result;
			}
		}

		public static void SetBuffer(List<string> buffer)
		{
			lock (logPath)
			{
				FileLog.buffer = buffer;
			}
		}

		public static void FlushBuffer()
		{
			lock (logPath)
			{
				if (buffer.Count <= 0)
				{
					return;
				}
				using (StreamWriter streamWriter = File.AppendText(logPath))
				{
					foreach (string item in buffer)
					{
						streamWriter.WriteLine(item);
					}
				}
				buffer.Clear();
			}
		}

		public static void Log(string str)
		{
			lock (logPath)
			{
				using StreamWriter streamWriter = File.AppendText(logPath);
				streamWriter.WriteLine(IndentString() + str);
			}
		}

		public static void Reset()
		{
			lock (logPath)
			{
				File.Delete($"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}{Path.DirectorySeparatorChar}harmony.log.txt");
			}
		}

		public unsafe static void LogBytes(long ptr, int len)
		{
			lock (logPath)
			{
				byte* ptr2 = (byte*)ptr;
				string text = "";
				for (int i = 1; i <= len; i++)
				{
					if (text == "")
					{
						text = "#  ";
					}
					text = $"{text}{*ptr2:X2} ";
					if (i > 1 || len == 1)
					{
						if (i % 8 == 0 || i == len)
						{
							Log(text);
							text = "";
						}
						else if (i % 4 == 0)
						{
							text += " ";
						}
					}
					ptr2++;
				}
				byte[] destination = new byte[len];
				Marshal.Copy((IntPtr)ptr, destination, 0, len);
				byte[] array = MD5.Create().ComputeHash(destination);
				StringBuilder stringBuilder = new StringBuilder();
				for (int j = 0; j < array.Length; j++)
				{
					stringBuilder.Append(array[j].ToString("X2"));
				}
				Log($"HASH: {stringBuilder}");
			}
		}
	}
	public static class AccessTools
	{
		public delegate ref U FieldRef<T, U>(T obj = default(T));

		public delegate ref F FieldRef<F>();

		public static BindingFlags all = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty;

		public static BindingFlags allDeclared = all | BindingFlags.DeclaredOnly;

		private static readonly MethodInfo m_PrepForRemoting = Method(typeof(Exception), "PrepForRemoting") ?? Method(typeof(Exception), "FixRemotingException");

		private static readonly FastInvokeHandler PrepForRemoting = MethodInvoker.GetHandler(m_PrepForRemoting);

		public static bool IsMonoRuntime { get; } = (object)Type.GetType("Mono.Runtime") != null;


		public static Type TypeByName(string name)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			Type type = Type.GetType(name, throwOnError: false);
			if ((object)type == null)
			{
				type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
					select assembly.GetType(name)).FirstOrDefault((Type t) => (object)t != null);
			}
			if ((object)type == null)
			{
				type = AppDomain.CurrentDomain.GetAssemblies().SelectMany((Assembly x) => x.GetTypes()).FirstOrDefault((Type x) => x.Name == name);
			}
			if ((object)type == null)
			{
				Logger.Log(Logger.LogChannel.Warn, () => "AccessTools.TypeByName: Could not find type named " + name);
			}
			return type;
		}

		public static T FindIncludingBaseTypes<T>(Type type, Func<Type, T> func) where T : class
		{
			while (true)
			{
				T val = func(type);
				if (val != null)
				{
					return val;
				}
				if ((object)type == typeof(object))
				{
					break;
				}
				type = type.BaseType;
			}
			return null;
		}

		public static T FindIncludingInnerTypes<T>(Type type, Func<Type, T> func) where T : class
		{
			T val = func(type);
			if (val != null)
			{
				return val;
			}
			Type[] nestedTypes = type.GetNestedTypes(all);
			for (int i = 0; i < nestedTypes.Length; i++)
			{
				val = FindIncludingInnerTypes(nestedTypes[i], func);
				if (val != null)
				{
					break;
				}
			}
			return val;
		}

		public static FieldInfo DeclaredField(Type type, string name)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			FieldInfo? field = type.GetField(name, allDeclared);
			if ((object)field == null)
			{
				Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.DeclaredField: Could not find field for type {type} and name {name}");
			}
			return field;
		}

		public static FieldInfo Field(Type type, string name)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			FieldInfo? fieldInfo = FindIncludingBaseTypes(type, (Type t) => t.GetField(name, all));
			if ((object)fieldInfo == null)
			{
				Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.Field: Could not find field for type {type} and name {name}");
			}
			return fieldInfo;
		}

		public static FieldInfo DeclaredField(Type type, int idx)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			FieldInfo? fieldInfo = GetDeclaredFields(type).ElementAtOrDefault(idx);
			if ((object)fieldInfo == null)
			{
				Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.DeclaredField: Could not find field for type {type} and idx {idx}");
			}
			return fieldInfo;
		}

		public static PropertyInfo DeclaredProperty(Type type, string name)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			try
			{
				PropertyInfo? property = type.GetProperty(name, allDeclared);
				if ((object)property == null)
				{
					Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.DeclaredProperty: Could not find property for type {type} and name {name}");
				}
				return property;
			}
			catch (AmbiguousMatchException inner)
			{
				throw new AmbiguousMatchException($"Ambiguous match for property {type}::{name}", inner);
			}
		}

		public static MethodInfo DeclaredPropertyGetter(Type type, string name)
		{
			return DeclaredProperty(type, name)?.GetGetMethod(nonPublic: true);
		}

		public static MethodInfo DeclaredPropertySetter(Type type, string name)
		{
			return DeclaredProperty(type, name)?.GetSetMethod(nonPublic: true);
		}

		public static PropertyInfo Property(Type type, string name)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			PropertyInfo? propertyInfo = FindIncludingBaseTypes(type, (Type t) => t.GetProperty(name, all));
			if ((object)propertyInfo == null)
			{
				Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.Property: Could not find property for type {type} and name {name}");
			}
			return propertyInfo;
		}

		public static MethodInfo PropertyGetter(Type type, string name)
		{
			return Property(type, name)?.GetGetMethod(nonPublic: true);
		}

		public static MethodInfo PropertySetter(Type type, string name)
		{
			return Property(type, name)?.GetSetMethod(nonPublic: true);
		}

		public static MethodInfo DeclaredMethod(Type type, string name, Type[] parameters = null, Type[] generics = null)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			ParameterModifier[] modifiers = new ParameterModifier[0];
			try
			{
				MethodInfo methodInfo = ((parameters != null) ? type.GetMethod(name, allDeclared, null, parameters, modifiers) : type.GetMethod(name, allDeclared));
				if ((object)methodInfo == null)
				{
					Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.DeclaredMethod: Could not find method for type {type} and name {name} and parameters {parameters?.Description()}");
					return null;
				}
				if (generics != null)
				{
					methodInfo = methodInfo.MakeGenericMethod(generics);
				}
				return methodInfo;
			}
			catch (AmbiguousMatchException inner)
			{
				string text = "";
				if (generics != null)
				{
					text = "<" + string.Join(", ", generics.Select((Type g) => g.FullName).ToArray()) + ">";
				}
				string text2 = "";
				if (parameters != null)
				{
					text2 = string.Join(", ", parameters.Select((Type p) => p.FullName).ToArray());
				}
				throw new AmbiguousMatchException($"Ambiguous match for {type}::{name}{text}(${text2})", inner);
			}
		}

		public static MethodInfo Method(Type type, string name, Type[] parameters = null, Type[] generics = null)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			try
			{
				ParameterModifier[] modifiers = new ParameterModifier[0];
				MethodInfo methodInfo;
				if (parameters == null)
				{
					try
					{
						methodInfo = FindIncludingBaseTypes(type, (Type t) => t.GetMethod(name, all));
					}
					catch (AmbiguousMatchException inner)
					{
						methodInfo = FindIncludingBaseTypes(type, (Type t) => t.GetMethod(name, all, null, new Type[0], modifiers));
						if ((object)methodInfo == null)
						{
							throw new AmbiguousMatchException($"Ambiguous match for {type}:{name}", inner);
						}
					}
				}
				else
				{
					methodInfo = FindIncludingBaseTypes(type, (Type t) => t.GetMethod(name, all, null, parameters, modifiers));
				}
				if ((object)methodInfo == null)
				{
					Logger.Log(Logger.LogChannel.Warn, () => $"AccessTools.Method: Could not find method for type {type} and name {name} and parameters {parameters?.Description()}");
					return null;
				}
				if (generics != null)
				{
					methodInfo = methodInfo.MakeGenericMethod(generics);
				}
				return methodInfo;
			}
			catch (AmbiguousMatchException inner2)
			{
				string text = "";
				if (generics != null)
				{
					text = "<" + string.Join(", ", generics.Select((Type g) => g.FullName).ToArray()) + ">";
				}
				string text2 = "";
				if (parameters != null)
				{
					text2 = string.Join(", ", parameters.Select((Type p) => p.FullName).ToArray());
				}
				throw new AmbiguousMatchException($"Ambiguous match for {type}::{name}{text}(${text2})", inner2);
			}
		}

		public static MethodInfo Method(string typeColonMethodname, Type[] parameters = null, Type[] generics = null)
		{
			if (typeColonMethodname == null)
			{
				throw new ArgumentNullException("typeColonMethodname");
			}
			string[] array = typeColonMethodname.Split(new char[1] { ':' });
			if (array.Length != 2)
			{
				throw new ArgumentException("Method must be specified as 'Namespace.Type1.Type2:MethodName", "typeColonMethodname");
			}
			return Method(TypeByName(array[0]), array[1], parameters, generics);
		}

		public static List<string> GetMethodNames(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return (from m in GetDeclaredMethods(type)
				select m.Name).ToList();
		}

		public static List<string> GetMethodNames(object instance)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			return GetMethodNames(instance.GetType());
		}

		public static List<string> GetFieldNames(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return (from f in GetDeclaredFields(type)
				select f.Name).ToList();
		}

		public static List<string> GetFieldNames(object instance)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			return GetFieldNames(instance.GetType());
		}

		public static List<string> GetPropertyNames(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return (from f in GetDeclaredProperties(type)
				select f.Name).ToList();
		}

		public static List<string> GetPropertyNames(object instance)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			return GetPropertyNames(instance.GetType());
		}

		public static Type GetUnderlyingType(this MemberInfo member)
		{
			if ((object)member == null)
			{
				throw new ArgumentNullException("member");
			}
			return member.MemberType switch
			{
				MemberTypes.Event => ((EventInfo)member).EventHandlerType, 
				MemberTypes.Field => ((FieldInfo)member).FieldType, 
				MemberTypes.Method => ((MethodInfo)member).ReturnType, 
				MemberTypes.Property => ((PropertyInfo)member).PropertyType, 
				_ => throw new ArgumentException("Member must be of type EventInfo, FieldInfo, MethodInfo, or PropertyInfo"), 
			};
		}

		public static ConstructorInfo DeclaredConstructor(Type type, Type[] parameters = null)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (parameters == null)
			{
				parameters = new Type[0];
			}
			return type.GetConstructor(allDeclared, null, parameters, new ParameterModifier[0]);
		}

		public static ConstructorInfo DeclaredConstructor(Type type, Type[] parameters, bool searchForStatic)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (parameters == null)
			{
				parameters = new Type[0];
			}
			BindingFlags bindingFlags = (searchForStatic ? BindingFlags.Instance : BindingFlags.Static);
			return type.GetConstructor(allDeclared & ~bindingFlags, null, parameters, new ParameterModifier[0]);
		}

		public static ConstructorInfo Constructor(Type type, Type[] parameters = null)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (parameters == null)
			{
				parameters = new Type[0];
			}
			return FindIncludingBaseTypes(type, (Type t) => t.GetConstructor(all, null, parameters, new ParameterModifier[0]));
		}

		public static ConstructorInfo Constructor(Type type, Type[] parameters, bool searchForStatic)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (parameters == null)
			{
				parameters = new Type[0];
			}
			BindingFlags exclude = (searchForStatic ? BindingFlags.Instance : BindingFlags.Static);
			return FindIncludingBaseTypes(type, (Type t) => t.GetConstructor(all & ~exclude, null, parameters, new ParameterModifier[0]));
		}

		public static List<ConstructorInfo> GetDeclaredConstructors(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return (from method in type.GetConstructors(allDeclared)
				where (object)method.DeclaringType == type
				select method).ToList();
		}

		public static List<ConstructorInfo> GetDeclaredConstructors(Type type, bool? searchForStatic)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			BindingFlags bindingFlags = BindingFlags.Default;
			if (searchForStatic.HasValue)
			{
				bindingFlags = (searchForStatic.Value ? BindingFlags.Instance : BindingFlags.Static);
			}
			return (from method in type.GetConstructors(allDeclared & ~bindingFlags)
				where (object)method.DeclaringType == type
				select method).ToList();
		}

		public static List<MethodInfo> GetDeclaredMethods(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return type.GetMethods(allDeclared).ToList();
		}

		public static List<PropertyInfo> GetDeclaredProperties(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return type.GetProperties(allDeclared).ToList();
		}

		public static List<FieldInfo> GetDeclaredFields(Type type)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			return type.GetFields(allDeclared).ToList();
		}

		public static Type GetReturnedType(MethodBase methodOrConstructor)
		{
			if ((object)methodOrConstructor == null)
			{
				throw new ArgumentNullException("methodOrConstructor");
			}
			if (methodOrConstructor is ConstructorInfo)
			{
				return typeof(void);
			}
			return ((MethodInfo)methodOrConstructor).ReturnType;
		}

		public static Type Inner(Type type, string name)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			return FindIncludingBaseTypes(type, (Type t) => t.GetNestedType(name, all));
		}

		public static Type FirstInner(Type type, Func<Type, bool> predicate)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			return type.GetNestedTypes(all).FirstOrDefault(predicate);
		}

		public static MethodInfo FirstMethod(Type type, Func<MethodInfo, bool> predicate)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			return type.GetMethods(allDeclared).FirstOrDefault(predicate);
		}

		public static ConstructorInfo FirstConstructor(Type type, Func<ConstructorInfo, bool> predicate)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			return type.GetConstructors(allDeclared).FirstOrDefault(predicate);
		}

		public static PropertyInfo FirstProperty(Type type, Func<PropertyInfo, bool> predicate)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			return type.GetProperties(allDeclared).FirstOrDefault(predicate);
		}

		public static Type[] GetTypes(object[] parameters)
		{
			if (parameters == null)
			{
				return new Type[0];
			}
			return parameters.Select((object p) => (p != null) ? p.GetType() : typeof(object)).ToArray();
		}

		public static object[] ActualParameters(MethodBase method, object[] inputs)
		{
			if ((object)method == null)
			{
				throw new ArgumentNullException("method");
			}
			if (inputs == null)
			{
				throw new ArgumentNullException("inputs");
			}
			List<Type> inputTypes = inputs.Select((object obj) => obj?.GetType()).ToList();
			return (from p in method.GetParameters()
				select p.ParameterType).Select(delegate(Type pType)
			{
				int num = inputTypes.FindIndex((Type inType) => inputTypes != null && pType.IsAssignableFrom(inType));
				return (num >= 0) ? inputs[num] : GetDefaultValue(pType);
			}).ToArray();
		}

		public static FieldRef<T, U> FieldRefAccess<T, U>(string fieldName)
		{
			return FieldRefAccess<T, U>(typeof(T).GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic));
		}

		public static FieldRef<T, U> FieldRefAccess<T, U>(FieldInfo fieldInfo)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!typeof(U).IsAssignableFrom(fieldInfo.FieldType))
			{
				throw new ArgumentException("FieldInfo type does not match FieldRefAccess return type.");
			}
			if ((object)typeof(T) != typeof(object) && ((object)fieldInfo.DeclaringType == null || !fieldInfo.DeclaringType.IsAssignableFrom(typeof(T))))
			{
				throw new MissingFieldException(typeof(T).Name, fieldInfo.Name);
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition("__refget_" + typeof(T).Name + "_fi_" + fieldInfo.Name, typeof(U).MakeByRefType(), new Type[1] { typeof(T) });
			ILGenerator iLGenerator = val.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldflda, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return Extensions.CreateDelegate<FieldRef<T, U>>((MethodBase)val.Generate());
		}

		public static ref U FieldRefAccess<T, U>(T instance, string fieldName)
		{
			return ref FieldRefAccess<T, U>(fieldName)(instance);
		}

		public static FieldRef<object, F> FieldRefAccess<F>(Type type, string fieldName)
		{
			return FieldRefAccess<object, F>(Field(type, fieldName));
		}

		public static ref F StaticFieldRefAccess<T, F>(string fieldName)
		{
			return ref StaticFieldRefAccess<F>(typeof(T), fieldName);
		}

		public static ref F StaticFieldRefAccess<T, F>(FieldInfo fieldInfo)
		{
			return ref StaticFieldRefAccess<F>(fieldInfo)();
		}

		public static FieldRef<F> StaticFieldRefAccess<F>(FieldInfo fieldInfo)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((object)fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			Type declaringType = fieldInfo.DeclaringType;
			DynamicMethodDefinition val = new DynamicMethodDefinition("__refget_" + declaringType.Name + "_static_fi_" + fieldInfo.Name, typeof(F).MakeByRefType(), new Type[0]);
			ILGenerator iLGenerator = val.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldsflda, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return Extensions.CreateDelegate<FieldRef<F>>((MethodBase)val.Generate());
		}

		public static ref F StaticFieldRefAccess<F>(Type type, string fieldName)
		{
			return ref StaticFieldRefAccess<F>(type.GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic))();
		}

		public static MethodBase GetOutsideCaller()
		{
			StackFrame[] frames = new StackTrace(fNeedFileInfo: true).GetFrames();
			for (int i = 0; i < frames.Length; i++)
			{
				Met

BepInEx/core/BepInEx.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.ConsoleUtil;
using BepInEx.Logging;
using BepInEx.Unix;
using HarmonyLib;
using HarmonyLib.Tools;
using Microsoft.Win32.SafeHandles;
using Mono.Cecil;
using MonoMod.Utils;
using UnityEngine;
using UnityInjector.ConsoleUtil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BepInEx")]
[assembly: AssemblyDescription("Unity plugin injection framework")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BepInEx")]
[assembly: AssemblyCopyright("Copyright © Bepis 2018")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4ffba620-f5ed-47f9-b90c-dad1316fd9b9")]
[assembly: InternalsVisibleTo("BepInEx.Preloader")]
[assembly: InternalsVisibleTo("BepInExTests")]
[assembly: AssemblyFileVersion("5.4.22.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("5.4.22.0")]
[module: UnverifiableCode]
namespace UnityEngine
{
	internal sealed class UnityLogWriter
	{
		[MethodImpl(MethodImplOptions.InternalCall)]
		public static extern void WriteStringToUnityLogImpl(string s);

		[MethodImpl(MethodImplOptions.InternalCall)]
		public static extern void WriteStringToUnityLog(string s);
	}
}
namespace UnityInjector.ConsoleUtil
{
	internal class ConsoleEncoding : Encoding
	{
		private byte[] _byteBuffer = new byte[256];

		private char[] _charBuffer = new char[256];

		private byte[] _zeroByte = new byte[0];

		private char[] _zeroChar = new char[0];

		private readonly uint _codePage;

		public override int CodePage => (int)_codePage;

		public static Encoding OutputEncoding => new ConsoleEncoding(ConsoleCodePage);

		public static uint ConsoleCodePage
		{
			get
			{
				return GetConsoleOutputCP();
			}
			set
			{
				SetConsoleOutputCP(value);
			}
		}

		private void ExpandByteBuffer(int count)
		{
			if (_byteBuffer.Length < count)
			{
				_byteBuffer = new byte[count];
			}
		}

		private void ExpandCharBuffer(int count)
		{
			if (_charBuffer.Length < count)
			{
				_charBuffer = new char[count];
			}
		}

		private void ReadByteBuffer(byte[] bytes, int index, int count)
		{
			for (int i = 0; i < count; i++)
			{
				bytes[index + i] = _byteBuffer[i];
			}
		}

		private void ReadCharBuffer(char[] chars, int index, int count)
		{
			for (int i = 0; i < count; i++)
			{
				chars[index + i] = _charBuffer[i];
			}
		}

		private void WriteByteBuffer(byte[] bytes, int index, int count)
		{
			ExpandByteBuffer(count);
			for (int i = 0; i < count; i++)
			{
				_byteBuffer[i] = bytes[index + i];
			}
		}

		private void WriteCharBuffer(char[] chars, int index, int count)
		{
			ExpandCharBuffer(count);
			for (int i = 0; i < count; i++)
			{
				_charBuffer[i] = chars[index + i];
			}
		}

		public static uint GetActiveCodePage()
		{
			return GetACP();
		}

		private ConsoleEncoding(uint codePage)
		{
			_codePage = codePage;
		}

		public static ConsoleEncoding GetEncoding(uint codePage)
		{
			return new ConsoleEncoding(codePage);
		}

		public override int GetByteCount(char[] chars, int index, int count)
		{
			WriteCharBuffer(chars, index, count);
			return WideCharToMultiByte(_codePage, 0u, _charBuffer, count, _zeroByte, 0, IntPtr.Zero, IntPtr.Zero);
		}

		public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
		{
			int byteCount = GetByteCount(chars, charIndex, charCount);
			WriteCharBuffer(chars, charIndex, charCount);
			ExpandByteBuffer(byteCount);
			int result = WideCharToMultiByte(_codePage, 0u, chars, charCount, _byteBuffer, byteCount, IntPtr.Zero, IntPtr.Zero);
			ReadByteBuffer(bytes, byteIndex, byteCount);
			return result;
		}

		public override int GetCharCount(byte[] bytes, int index, int count)
		{
			WriteByteBuffer(bytes, index, count);
			return MultiByteToWideChar(_codePage, 0u, bytes, count, _zeroChar, 0);
		}

		public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
		{
			int charCount = GetCharCount(bytes, byteIndex, byteCount);
			WriteByteBuffer(bytes, byteIndex, byteCount);
			ExpandCharBuffer(charCount);
			int result = MultiByteToWideChar(_codePage, 0u, bytes, byteCount, _charBuffer, charCount);
			ReadCharBuffer(chars, charIndex, charCount);
			return result;
		}

		public override int GetMaxByteCount(int charCount)
		{
			return charCount * 2;
		}

		public override int GetMaxCharCount(int byteCount)
		{
			return byteCount;
		}

		[DllImport("kernel32.dll")]
		private static extern uint GetConsoleOutputCP();

		[DllImport("kernel32.dll")]
		private static extern uint GetACP();

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern int MultiByteToWideChar(uint codePage, uint dwFlags, [In][MarshalAs(UnmanagedType.LPArray)] byte[] lpMultiByteStr, int cbMultiByte, [Out][MarshalAs(UnmanagedType.LPWStr)] char[] lpWideCharStr, int cchWideChar);

		[DllImport("kernel32.dll")]
		private static extern IntPtr SetConsoleOutputCP(uint codepage);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern int WideCharToMultiByte(uint codePage, uint dwFlags, [In][MarshalAs(UnmanagedType.LPWStr)] char[] lpWideCharStr, int cchWideChar, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] lpMultiByteStr, int cbMultiByte, IntPtr lpDefaultChar, IntPtr lpUsedDefaultChar);
	}
	internal class ConsoleWindow
	{
		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		[return: MarshalAs(UnmanagedType.Bool)]
		private delegate bool SetForegroundWindowDelegate(IntPtr hWnd);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		private delegate IntPtr GetForegroundWindowDelegate();

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		private delegate IntPtr GetSystemMenuDelegate(IntPtr hwnd, bool bRevert);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		private delegate bool DeleteMenuDelegate(IntPtr hMenu, uint uPosition, uint uFlags);

		private const uint SC_CLOSE = 61536u;

		private const uint MF_BYCOMMAND = 0u;

		private const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 2048u;

		public static IntPtr ConsoleOutHandle;

		public static IntPtr OriginalStdoutHandle;

		private static bool methodsInited;

		private static SetForegroundWindowDelegate setForeground;

		private static GetForegroundWindowDelegate getForeground;

		private static GetSystemMenuDelegate getSystemMenu;

		private static DeleteMenuDelegate deleteMenu;

		public static bool IsAttached { get; private set; }

		public static string Title
		{
			set
			{
				if (IsAttached)
				{
					if (value == null)
					{
						throw new ArgumentNullException("value");
					}
					if (value.Length > 24500)
					{
						throw new InvalidOperationException("Console title too long");
					}
					if (!SetConsoleTitle(value))
					{
						throw new InvalidOperationException("Console title invalid");
					}
				}
			}
		}

		public static void Attach()
		{
			if (!IsAttached)
			{
				Initialize();
				if (OriginalStdoutHandle == IntPtr.Zero)
				{
					OriginalStdoutHandle = GetStdHandle(-11);
				}
				IntPtr hWnd = getForeground();
				GetConsoleWindow();
				if (GetConsoleWindow() == IntPtr.Zero && !AllocConsole())
				{
					throw new Exception("AllocConsole() failed");
				}
				setForeground(hWnd);
				ConsoleOutHandle = CreateFile("CONOUT$", 3221225472u, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
				Kon.conOut = ConsoleOutHandle;
				if (!SetStdHandle(-11, ConsoleOutHandle))
				{
					throw new Exception("SetStdHandle() failed");
				}
				if (OriginalStdoutHandle != IntPtr.Zero && ConsoleManager.ConfigConsoleOutRedirectType.Value == ConsoleManager.ConsoleOutRedirectType.ConsoleOut)
				{
					CloseHandle(OriginalStdoutHandle);
				}
				IsAttached = true;
			}
		}

		public static void PreventClose()
		{
			if (IsAttached)
			{
				Initialize();
				IntPtr consoleWindow = GetConsoleWindow();
				IntPtr intPtr = getSystemMenu(consoleWindow, bRevert: false);
				if (intPtr != IntPtr.Zero)
				{
					deleteMenu(intPtr, 61536u, 0u);
				}
			}
		}

		public static void Detach()
		{
			if (IsAttached)
			{
				if (!CloseHandle(ConsoleOutHandle))
				{
					throw new Exception("CloseHandle() failed");
				}
				ConsoleOutHandle = IntPtr.Zero;
				if (!FreeConsole())
				{
					throw new Exception("FreeConsole() failed");
				}
				if (!SetStdHandle(-11, OriginalStdoutHandle))
				{
					throw new Exception("SetStdHandle() failed");
				}
				IsAttached = false;
			}
		}

		private static void Initialize()
		{
			if (!methodsInited)
			{
				methodsInited = true;
				IntPtr hModule = LoadLibraryEx("user32.dll", IntPtr.Zero, 2048u);
				setForeground = DynDll.AsDelegate<SetForegroundWindowDelegate>(GetProcAddress(hModule, "SetForegroundWindow"));
				getForeground = DynDll.AsDelegate<GetForegroundWindowDelegate>(GetProcAddress(hModule, "GetForegroundWindow"));
				getSystemMenu = DynDll.AsDelegate<GetSystemMenuDelegate>(GetProcAddress(hModule, "GetSystemMenu"));
				deleteMenu = DynDll.AsDelegate<DeleteMenuDelegate>(GetProcAddress(hModule, "DeleteMenu"));
			}
		}

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool AllocConsole();

		[DllImport("kernel32.dll")]
		private static extern IntPtr GetConsoleWindow();

		[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
		private static extern bool CloseHandle(IntPtr handle);

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		private static extern IntPtr CreateFile(string fileName, uint desiredAccess, int shareMode, IntPtr securityAttributes, int creationDisposition, int flagsAndAttributes, IntPtr templateFile);

		[DllImport("kernel32.dll")]
		private static extern bool FreeConsole();

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern IntPtr GetStdHandle(int nStdHandle);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput);

		[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)]
		private static extern bool SetConsoleTitle(string title);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern IntPtr LoadLibraryEx(string lpLibFileName, IntPtr hFile, uint dwFlags);
	}
	internal static class SafeConsole
	{
		private delegate ConsoleColor GetColorDelegate();

		private delegate void SetColorDelegate(ConsoleColor value);

		private delegate string GetStringDelegate();

		private delegate void SetStringDelegate(string value);

		private static GetColorDelegate _getBackgroundColor;

		private static SetColorDelegate _setBackgroundColor;

		private static GetColorDelegate _getForegroundColor;

		private static SetColorDelegate _setForegroundColor;

		private static GetStringDelegate _getTitle;

		private static SetStringDelegate _setTitle;

		public static bool BackgroundColorExists { get; private set; }

		public static ConsoleColor BackgroundColor
		{
			get
			{
				return _getBackgroundColor();
			}
			set
			{
				_setBackgroundColor(value);
			}
		}

		public static bool ForegroundColorExists { get; private set; }

		public static ConsoleColor ForegroundColor
		{
			get
			{
				return _getForegroundColor();
			}
			set
			{
				_setForegroundColor(value);
			}
		}

		public static bool TitleExists { get; private set; }

		public static string Title
		{
			get
			{
				return _getTitle();
			}
			set
			{
				_setTitle(value);
			}
		}

		static SafeConsole()
		{
			InitColors(typeof(Console));
		}

		private static void InitColors(Type tConsole)
		{
			MethodInfo method = tConsole.GetMethod("get_ForegroundColor", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method2 = tConsole.GetMethod("set_ForegroundColor", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method3 = tConsole.GetMethod("get_BackgroundColor", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method4 = tConsole.GetMethod("set_BackgroundColor", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method5 = tConsole.GetMethod("get_Title", BindingFlags.Static | BindingFlags.Public);
			MethodInfo method6 = tConsole.GetMethod("set_Title", BindingFlags.Static | BindingFlags.Public);
			_setForegroundColor = (((object)method2 != null) ? ((SetColorDelegate)Delegate.CreateDelegate(typeof(SetColorDelegate), method2)) : ((SetColorDelegate)delegate
			{
			}));
			_setBackgroundColor = (((object)method4 != null) ? ((SetColorDelegate)Delegate.CreateDelegate(typeof(SetColorDelegate), method4)) : ((SetColorDelegate)delegate
			{
			}));
			_getForegroundColor = (((object)method != null) ? ((GetColorDelegate)Delegate.CreateDelegate(typeof(GetColorDelegate), method)) : ((GetColorDelegate)(() => ConsoleColor.Gray)));
			_getBackgroundColor = (((object)method3 != null) ? ((GetColorDelegate)Delegate.CreateDelegate(typeof(GetColorDelegate), method3)) : ((GetColorDelegate)(() => ConsoleColor.Black)));
			_getTitle = (((object)method5 != null) ? ((GetStringDelegate)Delegate.CreateDelegate(typeof(GetStringDelegate), method5)) : ((GetStringDelegate)(() => string.Empty)));
			_setTitle = (((object)method6 != null) ? ((SetStringDelegate)Delegate.CreateDelegate(typeof(SetStringDelegate), method6)) : ((SetStringDelegate)delegate
			{
			}));
			BackgroundColorExists = _setBackgroundColor != null && _getBackgroundColor != null;
			ForegroundColorExists = _setForegroundColor != null && _getForegroundColor != null;
			TitleExists = _setTitle != null && _getTitle != null;
		}
	}
}
namespace BepInEx
{
	public static class UnityInput
	{
		private static IInputSystem _current;

		public static IInputSystem Current
		{
			get
			{
				if (_current != null)
				{
					return _current;
				}
				try
				{
					try
					{
						Input.GetKeyDown((KeyCode)97);
						_current = new LegacyInputSystem();
						Logger.LogDebug("[UnityInput] Using LegacyInputSystem");
					}
					catch (InvalidOperationException)
					{
						_current = new NewInputSystem();
						Logger.LogDebug("[UnityInput] Using NewInputSystem");
					}
				}
				catch (Exception arg)
				{
					Logger.LogWarning($"[UnityInput] Failed to detect available input systems - {arg}");
					_current = new NullInputSystem();
				}
				return _current;
			}
		}

		public static bool LegacyInputSystemAvailable => Current is LegacyInputSystem;
	}
	public interface IInputSystem
	{
		Vector3 mousePosition { get; }

		Vector2 mouseScrollDelta { get; }

		bool mousePresent { get; }

		bool anyKey { get; }

		bool anyKeyDown { get; }

		IEnumerable<KeyCode> SupportedKeyCodes { get; }

		bool GetKey(string name);

		bool GetKey(KeyCode key);

		bool GetKeyDown(string name);

		bool GetKeyDown(KeyCode key);

		bool GetKeyUp(string name);

		bool GetKeyUp(KeyCode key);

		bool GetMouseButton(int button);

		bool GetMouseButtonDown(int button);

		bool GetMouseButtonUp(int button);

		void ResetInputAxes();
	}
	internal class NewInputSystem : IInputSystem
	{
		private delegate bool GetButtonDelegate(KeyCode key);

		private delegate Vector2 GetMouseVectorDelegate();

		private delegate bool GetMouseStateDelegate();

		private static bool initialized;

		private static readonly Dictionary<KeyCode, int> keyCodeToIndex = new Dictionary<KeyCode, int>();

		private static readonly Dictionary<string, string> keyToKeyCodeNameRemap = new Dictionary<string, string>
		{
			["LeftCtrl"] = "LeftControl",
			["RightCtrl"] = "RightControl",
			["LeftMeta"] = "LeftApple",
			["RightMeta"] = "RightApple",
			["ContextMenu"] = "Menu",
			["PrintScreen"] = "Print",
			["Enter"] = "Return"
		};

		private static GetButtonDelegate _getKey;

		private static GetButtonDelegate _getKeyDown;

		private static GetButtonDelegate _getKeyUp;

		private static GetButtonDelegate _getMouseButton;

		private static GetButtonDelegate _getMouseButtonDown;

		private static GetButtonDelegate _getMouseButtonUp;

		private static GetMouseVectorDelegate _getMousePosition;

		private static GetMouseVectorDelegate _getMouseScrollDelta;

		private static GetMouseStateDelegate _getMousePresent;

		private static GetMouseStateDelegate _getKeyboardAnyKeyIsPressed;

		private static GetMouseStateDelegate _getKeyboardAnyKeyWasPressedThisFrame;

		public Vector3 mousePosition => Vector2.op_Implicit(_getMousePosition());

		public Vector2 mouseScrollDelta => _getMouseScrollDelta();

		public bool mousePresent => _getMousePresent();

		public bool anyKey
		{
			get
			{
				if (_getKeyboardAnyKeyIsPressed())
				{
					return true;
				}
				if (!GetMouseButton(0) && !GetMouseButton(1) && !GetMouseButton(2) && !GetMouseButton(3))
				{
					return GetMouseButton(4);
				}
				return true;
			}
		}

		public bool anyKeyDown
		{
			get
			{
				if (_getKeyboardAnyKeyWasPressedThisFrame())
				{
					return true;
				}
				if (!GetMouseButtonDown(0) && !GetMouseButtonDown(1) && !GetMouseButtonDown(2) && !GetMouseButtonDown(3))
				{
					return GetMouseButtonDown(4);
				}
				return true;
			}
		}

		public IEnumerable<KeyCode> SupportedKeyCodes => keyCodeToIndex.Keys.ToArray();

		public NewInputSystem()
		{
			Init();
		}

		private static void Init()
		{
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				return;
			}
			Assembly assembly = Assembly.Load("Unity.InputSystem");
			Type type = assembly.GetType("UnityEngine.InputSystem.Key");
			foreach (object value3 in Enum.GetValues(type))
			{
				string text = value3.ToString();
				int value = (int)value3;
				string value2;
				if (text.StartsWith("Numpad"))
				{
					text = text.Replace("Numpad", "Keypad");
				}
				else if (text.StartsWith("Digit"))
				{
					text = text.Replace("Digit", "Alpha");
				}
				else if (keyToKeyCodeNameRemap.TryGetValue(text, out value2))
				{
					text = value2;
				}
				if (TryEnumParse<KeyCode>(text, out var val))
				{
					keyCodeToIndex[val] = value;
				}
				else
				{
					Logger.LogDebug("[UnityInput] Unknown key name: " + text + ", skipping remapping");
				}
			}
			FieldInfo keyCodeToIndexField = AccessTools.Field(typeof(NewInputSystem), "keyCodeToIndex");
			MethodInfo tryGetValueMethod = AccessTools.Method(typeof(Dictionary<KeyCode, int>), "TryGetValue", (Type[])null, (Type[])null);
			Type type2 = assembly.GetType("UnityEngine.InputSystem.Keyboard");
			MethodInfo currentProperty = AccessTools.PropertyGetter(type2, "current");
			MethodInfo indexer = AccessTools.Method(type2, "get_Item", new Type[1] { type }, (Type[])null);
			Type buttonControlType = assembly.GetType("UnityEngine.InputSystem.Controls.ButtonControl");
			_getKey = GenerateKeyGetter("InputSystemGetKey", "isPressed");
			_getKeyDown = GenerateKeyGetter("InputSystemGetKeyDown", "wasPressedThisFrame");
			_getKeyUp = GenerateKeyGetter("InputSystemGetKeyUp", "wasReleasedThisFrame");
			Type mouseType = assembly.GetType("UnityEngine.InputSystem.Mouse");
			MethodInfo mouseCurrentProperty = AccessTools.PropertyGetter(mouseType, "current");
			string[] source = new string[5] { "leftButton", "rightButton", "middleButton", "backButton", "forwardButton" };
			MethodInfo[] buttonPropertyGetters = source.Select((string p) => AccessTools.PropertyGetter(mouseType, p)).ToArray();
			_getMouseButton = GenerateMouseGetter("InputSystemGetMouseButton", "isPressed");
			_getMouseButtonDown = GenerateMouseGetter("InputSystemGetMouseButtonDown", "wasPressedThisFrame");
			_getMouseButtonUp = GenerateMouseGetter("InputSystemGetMouseButtonUp", "wasReleasedThisFrame");
			_getMousePosition = GetPositionDelegate("InputSystemGetMousePosition", "position");
			_getMouseScrollDelta = GetPositionDelegate("InputSystemGetMouseScrollDelta", "scroll");
			DynamicMethodDefinition val2 = new DynamicMethodDefinition("InputSystemGetMouseEnabled", typeof(bool), Type.EmptyTypes);
			ILGenerator iLGenerator = val2.GetILGenerator();
			iLGenerator.Emit(OpCodes.Call, mouseCurrentProperty);
			iLGenerator.Emit(OpCodes.Callvirt, AccessTools.PropertyGetter(mouseType, "enabled"));
			iLGenerator.Emit(OpCodes.Ret);
			_getMousePresent = Extensions.CreateDelegate<GetMouseStateDelegate>((MethodBase)val2.Generate());
			MethodInfo anyKeyProperty = AccessTools.PropertyGetter(type2, "anyKey");
			_getKeyboardAnyKeyIsPressed = GetAnyKeyDelegate("InputSystemGetKeyboardAnyKeyIsPressed", "isPressed");
			_getKeyboardAnyKeyWasPressedThisFrame = GetAnyKeyDelegate("InputSystemGetKeyboardAnyKeyWasPressedThisFrame", "wasPressedThisFrame");
			initialized = true;
			GetButtonDelegate GenerateKeyGetter(string name, string property)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				MethodInfo meth4 = AccessTools.PropertyGetter(buttonControlType, property);
				DynamicMethodDefinition val6 = new DynamicMethodDefinition(name, typeof(bool), new Type[1] { typeof(KeyCode) });
				ILGenerator iLGenerator4 = val6.GetILGenerator();
				LocalBuilder local = iLGenerator4.DeclareLocal(typeof(int));
				Label label2 = iLGenerator4.DefineLabel();
				iLGenerator4.Emit(OpCodes.Ldsfld, keyCodeToIndexField);
				iLGenerator4.Emit(OpCodes.Ldarg_0);
				iLGenerator4.Emit(OpCodes.Ldloca, local);
				iLGenerator4.Emit(OpCodes.Callvirt, tryGetValueMethod);
				iLGenerator4.Emit(OpCodes.Brfalse, label2);
				iLGenerator4.Emit(OpCodes.Call, currentProperty);
				iLGenerator4.Emit(OpCodes.Ldloc, local);
				iLGenerator4.Emit(OpCodes.Callvirt, indexer);
				iLGenerator4.Emit(OpCodes.Callvirt, meth4);
				iLGenerator4.Emit(OpCodes.Ret);
				iLGenerator4.MarkLabel(label2);
				iLGenerator4.Emit(OpCodes.Ldc_I4_0);
				iLGenerator4.Emit(OpCodes.Ret);
				return Extensions.CreateDelegate<GetButtonDelegate>((MethodBase)val6.Generate());
			}
			GetButtonDelegate GenerateMouseGetter(string name, string property)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				MethodInfo meth3 = AccessTools.PropertyGetter(buttonControlType, property);
				DynamicMethodDefinition val5 = new DynamicMethodDefinition(name, typeof(bool), new Type[1] { typeof(KeyCode) });
				ILGenerator il = val5.GetILGenerator();
				il.Emit(OpCodes.Ldarg_0);
				il.Emit(OpCodes.Ldc_I4, 323);
				il.Emit(OpCodes.Sub);
				Label[] array = buttonPropertyGetters.Select((MethodInfo _) => il.DefineLabel()).ToArray();
				Label label = il.DefineLabel();
				il.Emit(OpCodes.Switch, array);
				il.Emit(OpCodes.Br, label);
				for (int i = 0; i < array.Length; i++)
				{
					il.MarkLabel(array[i]);
					il.Emit(OpCodes.Call, mouseCurrentProperty);
					il.Emit(OpCodes.Callvirt, buttonPropertyGetters[i]);
					il.Emit(OpCodes.Callvirt, meth3);
					il.Emit(OpCodes.Ret);
				}
				il.MarkLabel(label);
				il.Emit(OpCodes.Ldc_I4_0);
				il.Emit(OpCodes.Ret);
				return Extensions.CreateDelegate<GetButtonDelegate>((MethodBase)val5.Generate());
			}
			GetMouseStateDelegate GetAnyKeyDelegate(string name, string property)
			{
				//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)
				MethodInfo meth = AccessTools.PropertyGetter(buttonControlType, property);
				DynamicMethodDefinition val3 = new DynamicMethodDefinition(name, typeof(bool), Type.EmptyTypes);
				ILGenerator iLGenerator2 = val3.GetILGenerator();
				iLGenerator2.Emit(OpCodes.Call, currentProperty);
				iLGenerator2.Emit(OpCodes.Callvirt, anyKeyProperty);
				iLGenerator2.Emit(OpCodes.Callvirt, meth);
				iLGenerator2.Emit(OpCodes.Ret);
				return Extensions.CreateDelegate<GetMouseStateDelegate>((MethodBase)val3.Generate());
			}
			GetMouseVectorDelegate GetPositionDelegate(string name, string property)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				MethodInfo methodInfo = AccessTools.PropertyGetter(mouseType, property);
				MethodInfo meth2 = AccessTools.Method(methodInfo.ReturnType, "ReadValue", (Type[])null, (Type[])null);
				DynamicMethodDefinition val4 = new DynamicMethodDefinition(name, typeof(Vector2), Type.EmptyTypes);
				ILGenerator iLGenerator3 = val4.GetILGenerator();
				iLGenerator3.Emit(OpCodes.Call, mouseCurrentProperty);
				iLGenerator3.Emit(OpCodes.Callvirt, methodInfo);
				iLGenerator3.Emit(OpCodes.Callvirt, meth2);
				iLGenerator3.Emit(OpCodes.Ret);
				return Extensions.CreateDelegate<GetMouseVectorDelegate>((MethodBase)val4.Generate());
			}
		}

		public bool GetKey(string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _getKey(GetKeyCode(name));
		}

		public bool GetKey(KeyCode key)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return _getKey(key);
		}

		public bool GetKeyDown(string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _getKeyDown(GetKeyCode(name));
		}

		public bool GetKeyDown(KeyCode key)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return _getKeyDown(key);
		}

		public bool GetKeyUp(string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _getKeyUp(GetKeyCode(name));
		}

		public bool GetKeyUp(KeyCode key)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return _getKeyUp(key);
		}

		public bool GetMouseButton(int button)
		{
			return _getMouseButton((KeyCode)(323 + button));
		}

		public bool GetMouseButtonDown(int button)
		{
			return _getMouseButtonDown((KeyCode)(323 + button));
		}

		public bool GetMouseButtonUp(int button)
		{
			return _getMouseButtonUp((KeyCode)(323 + button));
		}

		public void ResetInputAxes()
		{
		}

		private static KeyCode GetKeyCode(string name)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return (KeyCode)Enum.Parse(typeof(KeyCode), name, ignoreCase: true);
		}

		private static bool TryEnumParse<T>(string name, out T val)
		{
			try
			{
				val = (T)Enum.Parse(typeof(T), name, ignoreCase: true);
				return true;
			}
			catch (Exception)
			{
				val = default(T);
				return false;
			}
		}
	}
	internal class LegacyInputSystem : IInputSystem
	{
		public Vector3 mousePosition => Input.mousePosition;

		public Vector2 mouseScrollDelta => Input.mouseScrollDelta;

		public bool mousePresent => Input.mousePresent;

		public bool anyKey => Input.anyKey;

		public bool anyKeyDown => Input.anyKeyDown;

		public IEnumerable<KeyCode> SupportedKeyCodes { get; } = (KeyCode[])Enum.GetValues(typeof(KeyCode));


		public bool GetKey(string name)
		{
			return Input.GetKey(name);
		}

		public bool GetKey(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKey(key);
		}

		public bool GetKeyDown(string name)
		{
			return Input.GetKeyDown(name);
		}

		public bool GetKeyDown(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyDown(key);
		}

		public bool GetKeyUp(string name)
		{
			return Input.GetKeyUp(name);
		}

		public bool GetKeyUp(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKeyUp(key);
		}

		public bool GetMouseButton(int button)
		{
			return Input.GetMouseButton(button);
		}

		public bool GetMouseButtonDown(int button)
		{
			return Input.GetMouseButtonDown(button);
		}

		public bool GetMouseButtonUp(int button)
		{
			return Input.GetMouseButtonUp(button);
		}

		public void ResetInputAxes()
		{
			Input.ResetInputAxes();
		}
	}
	internal class NullInputSystem : IInputSystem
	{
		private static readonly KeyCode[] NoKeys = (KeyCode[])(object)new KeyCode[0];

		public Vector3 mousePosition => Vector3.zero;

		public Vector2 mouseScrollDelta => Vector2.zero;

		public bool mousePresent => false;

		public bool anyKey => false;

		public bool anyKeyDown => false;

		public IEnumerable<KeyCode> SupportedKeyCodes => NoKeys;

		public bool GetKey(string name)
		{
			return false;
		}

		public bool GetKey(KeyCode key)
		{
			return false;
		}

		public bool GetKeyDown(string name)
		{
			return false;
		}

		public bool GetKeyDown(KeyCode key)
		{
			return false;
		}

		public bool GetKeyUp(string name)
		{
			return false;
		}

		public bool GetKeyUp(KeyCode key)
		{
			return false;
		}

		public bool GetMouseButton(int button)
		{
			return false;
		}

		public bool GetMouseButtonDown(int button)
		{
			return false;
		}

		public bool GetMouseButtonUp(int button)
		{
			return false;
		}

		public void ResetInputAxes()
		{
		}
	}
	internal static class ConsoleManager
	{
		public enum ConsoleOutRedirectType
		{
			[Description("Auto")]
			Auto,
			[Description("Console Out")]
			ConsoleOut,
			[Description("Standard Out")]
			StandardOut
		}

		private const uint SHIFT_JIS_CP = 932u;

		private static readonly bool? EnableConsoleArgOverride;

		private const string ENABLE_CONSOLE_ARG = "--enable-console";

		public static readonly ConfigEntry<bool> ConfigConsoleEnabled;

		public static readonly ConfigEntry<bool> ConfigPreventClose;

		public static readonly ConfigEntry<bool> ConfigConsoleShiftJis;

		public static readonly ConfigEntry<ConsoleOutRedirectType> ConfigConsoleOutRedirectType;

		internal static IConsoleDriver Driver { get; set; }

		public static bool ConsoleActive => Driver?.ConsoleActive ?? false;

		public static TextWriter StandardOutStream => Driver?.StandardOut;

		public static TextWriter ConsoleStream => Driver?.ConsoleOut;

		public static bool ConsoleEnabled => EnableConsoleArgOverride ?? ConfigConsoleEnabled.Value;

		static ConsoleManager()
		{
			ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind("Logging.Console", "Enabled", defaultValue: false, "Enables showing a console for log output.");
			ConfigPreventClose = ConfigFile.CoreConfig.Bind("Logging.Console", "PreventClose", defaultValue: false, "If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way).");
			ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind("Logging.Console", "ShiftJisEncoding", defaultValue: false, "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
			ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind("Logging.Console", "StandardOutType", ConsoleOutRedirectType.Auto, new StringBuilder().AppendLine("Hints console manager on what handle to assign as StandardOut. Possible values:").AppendLine("Auto - lets BepInEx decide how to redirect console output").AppendLine("ConsoleOut - prefer redirecting to console output; if possible, closes original standard output")
				.AppendLine("StandardOut - prefer redirecting to standard output; if possible, closes console out")
				.ToString());
			try
			{
				string[] commandLineArgs = Environment.GetCommandLineArgs();
				for (int i = 0; i < commandLineArgs.Length; i++)
				{
					if (commandLineArgs[i] == "--enable-console" && i + 1 < commandLineArgs.Length && bool.TryParse(commandLineArgs[i + 1], out var result))
					{
						EnableConsoleArgOverride = result;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public static void Initialize(bool alreadyActive)
		{
			if (PlatformHelper.Is((Platform)8))
			{
				Driver = new LinuxConsoleDriver();
			}
			else if (PlatformHelper.Is((Platform)37))
			{
				Driver = new WindowsConsoleDriver();
			}
			Driver.Initialize(alreadyActive);
		}

		private static void DriverCheck()
		{
			if (Driver == null)
			{
				throw new InvalidOperationException("Driver has not been initialized");
			}
		}

		public static void CreateConsole()
		{
			if (!ConsoleActive)
			{
				DriverCheck();
				uint codepage = (ConfigConsoleShiftJis.Value ? 932u : ((uint)Encoding.UTF8.CodePage));
				Driver.CreateConsole(codepage);
				if (ConfigPreventClose.Value)
				{
					Driver.PreventClose();
				}
			}
		}

		public static void DetachConsole()
		{
			if (ConsoleActive)
			{
				DriverCheck();
				Driver.DetachConsole();
			}
		}

		public static void SetConsoleTitle(string title)
		{
			DriverCheck();
			Driver.SetConsoleTitle(title);
		}

		public static void SetConsoleColor(ConsoleColor color)
		{
			DriverCheck();
			Driver.SetConsoleColor(color);
		}
	}
	internal interface IConsoleDriver
	{
		TextWriter StandardOut { get; }

		TextWriter ConsoleOut { get; }

		bool ConsoleActive { get; }

		bool ConsoleIsExternal { get; }

		void PreventClose();

		void Initialize(bool alreadyActive);

		void CreateConsole(uint codepage);

		void DetachConsole();

		void SetConsoleColor(ConsoleColor color);

		void SetConsoleTitle(string title);
	}
	internal class WindowsConsoleDriver : IConsoleDriver
	{
		private static readonly ConstructorInfo FileStreamCtor = new ConstructorInfo[2]
		{
			AccessTools.Constructor(typeof(FileStream), new Type[2]
			{
				typeof(SafeFileHandle),
				typeof(FileAccess)
			}, false),
			AccessTools.Constructor(typeof(FileStream), new Type[2]
			{
				typeof(IntPtr),
				typeof(FileAccess)
			}, false)
		}.FirstOrDefault((ConstructorInfo m) => (object)m != null);

		public TextWriter StandardOut { get; private set; }

		public TextWriter ConsoleOut { get; private set; }

		public bool ConsoleActive { get; private set; }

		public bool ConsoleIsExternal => true;

		public void PreventClose()
		{
			ConsoleWindow.PreventClose();
		}

		public void Initialize(bool alreadyActive)
		{
			ConsoleActive = alreadyActive;
			StandardOut = Console.Out;
		}

		private static FileStream OpenFileStream(IntPtr handle)
		{
			SafeFileHandle safeFileHandle = new SafeFileHandle(handle, ownsHandle: false);
			object[] args = AccessTools.ActualParameters((MethodBase)FileStreamCtor, new object[3]
			{
				safeFileHandle,
				safeFileHandle.DangerousGetHandle(),
				FileAccess.Write
			});
			return (FileStream)Activator.CreateInstance(typeof(FileStream), args);
		}

		public void CreateConsole(uint codepage)
		{
			ConsoleWindow.Attach();
			ConsoleEncoding.ConsoleCodePage = codepage;
			IntPtr outHandle = GetOutHandle();
			if (outHandle == IntPtr.Zero)
			{
				StandardOut = TextWriter.Null;
				ConsoleOut = TextWriter.Null;
				return;
			}
			FileStream stream = OpenFileStream(outHandle);
			StandardOut = new StreamWriter(stream, Utility.UTF8NoBom)
			{
				AutoFlush = true
			};
			FileStream stream2 = OpenFileStream(ConsoleWindow.ConsoleOutHandle);
			ConsoleOut = new StreamWriter(stream2, ConsoleEncoding.OutputEncoding)
			{
				AutoFlush = true
			};
			ConsoleActive = true;
		}

		private IntPtr GetOutHandle()
		{
			switch (ConsoleManager.ConfigConsoleOutRedirectType.Value)
			{
			case ConsoleManager.ConsoleOutRedirectType.ConsoleOut:
				return ConsoleWindow.ConsoleOutHandle;
			case ConsoleManager.ConsoleOutRedirectType.StandardOut:
				return ConsoleWindow.OriginalStdoutHandle;
			default:
				if (!(ConsoleWindow.OriginalStdoutHandle != IntPtr.Zero))
				{
					return ConsoleWindow.ConsoleOutHandle;
				}
				return ConsoleWindow.OriginalStdoutHandle;
			}
		}

		public void DetachConsole()
		{
			ConsoleWindow.Detach();
			ConsoleOut.Close();
			ConsoleOut = null;
			ConsoleActive = false;
		}

		public void SetConsoleColor(ConsoleColor color)
		{
			SafeConsole.ForegroundColor = color;
			Kon.ForegroundColor = color;
		}

		public void SetConsoleTitle(string title)
		{
			ConsoleWindow.Title = title;
		}
	}
	public class PluginInfo : ICacheable
	{
		public BepInPlugin Metadata { get; internal set; }

		public IEnumerable<BepInProcess> Processes { get; internal set; }

		public IEnumerable<BepInDependency> Dependencies { get; internal set; }

		public IEnumerable<BepInIncompatibility> Incompatibilities { get; internal set; }

		public string Location { get; internal set; }

		public BaseUnityPlugin Instance { get; internal set; }

		internal string TypeName { get; set; }

		internal Version TargettedBepInExVersion { get; set; }

		void ICacheable.Save(BinaryWriter bw)
		{
			bw.Write(TypeName);
			bw.Write(Metadata.GUID);
			bw.Write(Metadata.Name);
			bw.Write(Metadata.Version.ToString());
			List<BepInProcess> list = Processes.ToList();
			bw.Write(list.Count);
			foreach (BepInProcess item in list)
			{
				bw.Write(item.ProcessName);
			}
			List<BepInDependency> list2 = Dependencies.ToList();
			bw.Write(list2.Count);
			foreach (BepInDependency item2 in list2)
			{
				((ICacheable)item2).Save(bw);
			}
			List<BepInIncompatibility> list3 = Incompatibilities.ToList();
			bw.Write(list3.Count);
			foreach (BepInIncompatibility item3 in list3)
			{
				((ICacheable)item3).Save(bw);
			}
			bw.Write(TargettedBepInExVersion.ToString(4));
		}

		void ICacheable.Load(BinaryReader br)
		{
			TypeName = br.ReadString();
			Metadata = new BepInPlugin(br.ReadString(), br.ReadString(), br.ReadString());
			int num = br.ReadInt32();
			List<BepInProcess> list = new List<BepInProcess>(num);
			for (int i = 0; i < num; i++)
			{
				list.Add(new BepInProcess(br.ReadString()));
			}
			Processes = list;
			int num2 = br.ReadInt32();
			List<BepInDependency> list2 = new List<BepInDependency>(num2);
			for (int j = 0; j < num2; j++)
			{
				BepInDependency bepInDependency = new BepInDependency("");
				((ICacheable)bepInDependency).Load(br);
				list2.Add(bepInDependency);
			}
			Dependencies = list2;
			int num3 = br.ReadInt32();
			List<BepInIncompatibility> list3 = new List<BepInIncompatibility>(num3);
			for (int k = 0; k < num3; k++)
			{
				BepInIncompatibility bepInIncompatibility = new BepInIncompatibility("");
				((ICacheable)bepInIncompatibility).Load(br);
				list3.Add(bepInIncompatibility);
			}
			Incompatibilities = list3;
			TargettedBepInExVersion = new Version(br.ReadString());
		}

		public override string ToString()
		{
			return $"{Metadata?.Name} {Metadata?.Version}";
		}
	}
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
	public class BepInPlugin : Attribute
	{
		public string GUID { get; protected set; }

		public string Name { get; protected set; }

		public Version Version { get; protected set; }

		public BepInPlugin(string GUID, string Name, string Version)
		{
			this.GUID = GUID;
			this.Name = Name;
			try
			{
				this.Version = new Version(Version);
			}
			catch
			{
				this.Version = null;
			}
		}

		internal static BepInPlugin FromCecilType(TypeDefinition td)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			CustomAttribute val = MetadataHelper.GetCustomAttributes<BepInPlugin>(td, inherit: false).FirstOrDefault();
			if (val == null)
			{
				return null;
			}
			CustomAttributeArgument val2 = val.ConstructorArguments[0];
			string gUID = (string)((CustomAttributeArgument)(ref val2)).Value;
			val2 = val.ConstructorArguments[1];
			string name = (string)((CustomAttributeArgument)(ref val2)).Value;
			val2 = val.ConstructorArguments[2];
			return new BepInPlugin(gUID, name, (string)((CustomAttributeArgument)(ref val2)).Value);
		}
	}
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
	public class BepInDependency : Attribute, ICacheable
	{
		[Flags]
		public enum DependencyFlags
		{
			HardDependency = 1,
			SoftDependency = 2
		}

		public string DependencyGUID { get; protected set; }

		public DependencyFlags Flags { get; protected set; }

		public Version MinimumVersion { get; protected set; }

		public BepInDependency(string DependencyGUID, DependencyFlags Flags = DependencyFlags.HardDependency)
		{
			this.DependencyGUID = DependencyGUID;
			this.Flags = Flags;
			MinimumVersion = new Version();
		}

		public BepInDependency(string DependencyGUID, string MinimumDependencyVersion)
			: this(DependencyGUID)
		{
			MinimumVersion = new Version(MinimumDependencyVersion);
		}

		internal static IEnumerable<BepInDependency> FromCecilType(TypeDefinition td)
		{
			return MetadataHelper.GetCustomAttributes<BepInDependency>(td, inherit: true).Select(delegate(CustomAttribute customAttribute)
			{
				//IL_0007: 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)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				CustomAttributeArgument val = customAttribute.ConstructorArguments[0];
				string dependencyGUID = (string)((CustomAttributeArgument)(ref val)).Value;
				val = customAttribute.ConstructorArguments[1];
				object value = ((CustomAttributeArgument)(ref val)).Value;
				return (value is string minimumDependencyVersion) ? new BepInDependency(dependencyGUID, minimumDependencyVersion) : new BepInDependency(dependencyGUID, (DependencyFlags)value);
			}).ToList();
		}

		void ICacheable.Save(BinaryWriter bw)
		{
			bw.Write(DependencyGUID);
			bw.Write((int)Flags);
			bw.Write(MinimumVersion.ToString());
		}

		void ICacheable.Load(BinaryReader br)
		{
			DependencyGUID = br.ReadString();
			Flags = (DependencyFlags)br.ReadInt32();
			MinimumVersion = new Version(br.ReadString());
		}
	}
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
	public class BepInIncompatibility : Attribute, ICacheable
	{
		public string IncompatibilityGUID { get; protected set; }

		public BepInIncompatibility(string IncompatibilityGUID)
		{
			this.IncompatibilityGUID = IncompatibilityGUID;
		}

		internal static IEnumerable<BepInIncompatibility> FromCecilType(TypeDefinition td)
		{
			return MetadataHelper.GetCustomAttributes<BepInIncompatibility>(td, inherit: true).Select(delegate(CustomAttribute customAttribute)
			{
				//IL_0007: 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)
				CustomAttributeArgument val = customAttribute.ConstructorArguments[0];
				return new BepInIncompatibility((string)((CustomAttributeArgument)(ref val)).Value);
			}).ToList();
		}

		void ICacheable.Save(BinaryWriter bw)
		{
			bw.Write(IncompatibilityGUID);
		}

		void ICacheable.Load(BinaryReader br)
		{
			IncompatibilityGUID = br.ReadString();
		}
	}
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
	public class BepInProcess : Attribute
	{
		public string ProcessName { get; protected set; }

		public BepInProcess(string ProcessName)
		{
			this.ProcessName = ProcessName;
		}

		internal static List<BepInProcess> FromCecilType(TypeDefinition td)
		{
			return MetadataHelper.GetCustomAttributes<BepInProcess>(td, inherit: true).Select(delegate(CustomAttribute customAttribute)
			{
				//IL_0007: 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)
				CustomAttributeArgument val = customAttribute.ConstructorArguments[0];
				return new BepInProcess((string)((CustomAttributeArgument)(ref val)).Value);
			}).ToList();
		}
	}
	public static class MetadataHelper
	{
		internal static IEnumerable<CustomAttribute> GetCustomAttributes<T>(TypeDefinition td, bool inherit) where T : Attribute
		{
			List<CustomAttribute> list = new List<CustomAttribute>();
			Type type = typeof(T);
			TypeDefinition val = td;
			do
			{
				list.AddRange(((IEnumerable<CustomAttribute>)val.CustomAttributes).Where((CustomAttribute ca) => ((MemberReference)ca.AttributeType).FullName == type.FullName));
				TypeReference baseType = val.BaseType;
				val = ((baseType != null) ? baseType.Resolve() : null);
			}
			while (inherit && ((val != null) ? ((MemberReference)val).FullName : null) != "System.Object");
			return list;
		}

		public static BepInPlugin GetMetadata(Type pluginType)
		{
			object[] customAttributes = pluginType.GetCustomAttributes(typeof(BepInPlugin), inherit: false);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return (BepInPlugin)customAttributes[0];
		}

		public static BepInPlugin GetMetadata(object plugin)
		{
			return GetMetadata(plugin.GetType());
		}

		public static T[] GetAttributes<T>(Type pluginType) where T : Attribute
		{
			return (T[])pluginType.GetCustomAttributes(typeof(T), inherit: true);
		}

		public static IEnumerable<T> GetAttributes<T>(object plugin) where T : Attribute
		{
			return GetAttributes<T>(plugin.GetType());
		}

		public static IEnumerable<BepInDependency> GetDependencies(Type plugin)
		{
			return plugin.GetCustomAttributes(typeof(BepInDependency), inherit: true).Cast<BepInDependency>();
		}
	}
	internal class BuildInfoAttribute : Attribute
	{
		public string Info { get; }

		public BuildInfoAttribute(string info)
		{
			Info = info;
		}
	}
	public abstract class BaseUnityPlugin : MonoBehaviour
	{
		public PluginInfo Info { get; }

		protected ManualLogSource Logger { get; }

		public ConfigFile Config { get; }

		protected BaseUnityPlugin()
		{
			BepInPlugin metadata = MetadataHelper.GetMetadata(this);
			if (metadata == null)
			{
				throw new InvalidOperationException("Can't create an instance of " + ((object)this).GetType().FullName + " because it inherits from BaseUnityPlugin and the BepInPlugin attribute is missing.");
			}
			if (!Chainloader.IsEditor && Chainloader.PluginInfos.TryGetValue(metadata.GUID, out var value))
			{
				Info = value;
			}
			else
			{
				Info = new PluginInfo
				{
					Metadata = metadata,
					Instance = this,
					Dependencies = MetadataHelper.GetDependencies(((object)this).GetType()),
					Processes = MetadataHelper.GetAttributes<BepInProcess>(((object)this).GetType()),
					Location = ((object)this).GetType().Assembly.Location
				};
			}
			Logger = BepInEx.Logging.Logger.CreateLogSource(metadata.Name);
			string text = (Chainloader.IsEditor ? "." : Paths.ConfigPath);
			Config = new ConfigFile(Utility.CombinePaths(text, metadata.GUID + ".cfg"), saveOnInit: false, metadata);
		}
	}
	public static class Paths
	{
		public static string[] DllSearchPaths { get; private set; }

		public static string BepInExAssemblyDirectory { get; private set; }

		public static string BepInExAssemblyPath { get; private set; }

		public static string BepInExRootPath { get; private set; }

		public static string ExecutablePath { get; private set; }

		public static string GameRootPath { get; private set; }

		public static string ManagedPath { get; private set; }

		public static string ConfigPath { get; private set; }

		public static string BepInExConfigPath { get; private set; }

		public static string CachePath { get; private set; }

		public static string PatcherPluginPath { get; private set; }

		public static string PluginPath { get; private set; }

		public static string ProcessName { get; private set; }

		internal static void SetExecutablePath(string executablePath, string bepinRootPath = null, string managedPath = null, string[] dllSearchPath = null)
		{
			ExecutablePath = executablePath;
			ProcessName = Path.GetFileNameWithoutExtension(executablePath);
			GameRootPath = (PlatformHelper.Is((Platform)73) ? Utility.ParentDirectory(executablePath, 4) : Path.GetDirectoryName(executablePath));
			ManagedPath = managedPath ?? Utility.CombinePaths(GameRootPath, ProcessName + "_Data", "Managed");
			BepInExRootPath = bepinRootPath ?? Path.Combine(GameRootPath, "BepInEx");
			ConfigPath = Path.Combine(BepInExRootPath, "config");
			BepInExConfigPath = Path.Combine(ConfigPath, "BepInEx.cfg");
			PluginPath = Path.Combine(BepInExRootPath, "plugins");
			PatcherPluginPath = Path.Combine(BepInExRootPath, "patchers");
			BepInExAssemblyDirectory = Path.Combine(BepInExRootPath, "core");
			BepInExAssemblyPath = Path.Combine(BepInExAssemblyDirectory, Assembly.GetExecutingAssembly().GetName().Name + ".dll");
			CachePath = Path.Combine(BepInExRootPath, "cache");
			DllSearchPaths = (dllSearchPath ?? new string[0]).Concat(new string[1] { ManagedPath }).Distinct().ToArray();
		}

		internal static void SetManagedPath(string managedPath)
		{
			if (managedPath != null)
			{
				ManagedPath = managedPath;
			}
		}

		internal static void SetPluginPath(string pluginPath)
		{
			PluginPath = Utility.CombinePaths(BepInExRootPath, pluginPath);
		}
	}
	public sealed class ThreadingHelper : MonoBehaviour, ISynchronizeInvoke
	{
		private sealed class InvokeResult : IAsyncResult
		{
			internal bool ExceptionThrown;

			public bool IsCompleted { get; private set; }

			public WaitHandle AsyncWaitHandle { get; }

			public object AsyncState { get; private set; }

			public bool CompletedSynchronously { get; private set; }

			public InvokeResult()
			{
				AsyncWaitHandle = new EventWaitHandle(initialState: false, EventResetMode.ManualReset);
			}

			public void Finish(object result, bool completedSynchronously)
			{
				AsyncState = result;
				CompletedSynchronously = completedSynchronously;
				IsCompleted = true;
				((EventWaitHandle)AsyncWaitHandle).Set();
			}
		}

		private readonly object _invokeLock = new object();

		private Action _invokeList;

		private Thread _mainThread;

		public static ThreadingHelper Instance { get; private set; }

		public static ISynchronizeInvoke SynchronizingObject => Instance;

		public bool InvokeRequired
		{
			get
			{
				if (_mainThread != null)
				{
					return _mainThread != Thread.CurrentThread;
				}
				return true;
			}
		}

		internal static void Initialize()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("BepInEx_ThreadingHelper");
			if (Chainloader.ConfigHideBepInExGOs.Value)
			{
				((Object)val).hideFlags = (HideFlags)61;
			}
			Object.DontDestroyOnLoad((Object)(object)val);
			Instance = val.AddComponent<ThreadingHelper>();
		}

		public void StartSyncInvoke(Action action)
		{
			if (action == null)
			{
				throw new ArgumentNullException("action");
			}
			lock (_invokeLock)
			{
				_invokeList = (Action)Delegate.Combine(_invokeList, action);
			}
		}

		private void Update()
		{
			if (_mainThread == null)
			{
				_mainThread = Thread.CurrentThread;
			}
			if (_invokeList == null)
			{
				return;
			}
			Action invokeList;
			lock (_invokeLock)
			{
				invokeList = _invokeList;
				_invokeList = null;
			}
			foreach (Action item in invokeList.GetInvocationList().Cast<Action>())
			{
				try
				{
					item();
				}
				catch (Exception ex)
				{
					LogInvocationException(ex);
				}
			}
		}

		public void StartAsyncInvoke(Func<Action> action)
		{
			if (!ThreadPool.QueueUserWorkItem(DoWork))
			{
				throw new NotSupportedException("Failed to queue the action on ThreadPool");
			}
			void DoWork(object _)
			{
				try
				{
					Action action2 = action();
					if (action2 != null)
					{
						StartSyncInvoke(action2);
					}
				}
				catch (Exception ex)
				{
					LogInvocationException(ex);
				}
			}
		}

		private static void LogInvocationException(Exception ex)
		{
			Logger.Log(LogLevel.Error, ex);
			if (ex.InnerException != null)
			{
				Logger.Log(LogLevel.Error, "INNER: " + ex.InnerException);
			}
		}

		IAsyncResult ISynchronizeInvoke.BeginInvoke(Delegate method, object[] args)
		{
			InvokeResult result = new InvokeResult();
			if (!InvokeRequired)
			{
				result.Finish(Invoke(), completedSynchronously: true);
			}
			else
			{
				StartSyncInvoke(delegate
				{
					result.Finish(Invoke(), completedSynchronously: false);
				});
			}
			return result;
			object Invoke()
			{
				try
				{
					return method.DynamicInvoke(args);
				}
				catch (Exception result2)
				{
					result.ExceptionThrown = true;
					return result2;
				}
			}
		}

		object ISynchronizeInvoke.EndInvoke(IAsyncResult result)
		{
			InvokeResult invokeResult = (InvokeResult)result;
			invokeResult.AsyncWaitHandle.WaitOne();
			if (invokeResult.ExceptionThrown)
			{
				throw (Exception)invokeResult.AsyncState;
			}
			return invokeResult.AsyncState;
		}

		object ISynchronizeInvoke.Invoke(Delegate method, object[] args)
		{
			IAsyncResult result = ((ISynchronizeInvoke)this).BeginInvoke(method, args);
			return ((ISynchronizeInvoke)this).EndInvoke(result);
		}
	}
	public static class ThreadingExtensions
	{
		public static IEnumerable<TOut> RunParallel<TIn, TOut>(this IEnumerable<TIn> data, Func<TIn, TOut> work, int workerCount = -1)
		{
			foreach (TOut item in data.ToList().RunParallel(work))
			{
				yield return item;
			}
		}

		public static IEnumerable<TOut> RunParallel<TIn, TOut>(this IList<TIn> data, Func<TIn, TOut> work, int workerCount = -1)
		{
			if (workerCount < 0)
			{
				workerCount = Mathf.Max(2, Environment.ProcessorCount);
			}
			else if (workerCount == 0)
			{
				throw new ArgumentException("Need at least 1 worker", "workerCount");
			}
			int perThreadCount = Mathf.CeilToInt((float)data.Count / (float)workerCount);
			int doneCount = 0;
			object lockObj = new object();
			ManualResetEvent are = new ManualResetEvent(initialState: false);
			IEnumerable<TOut> doneItems = null;
			Exception exceptionThrown = null;
			for (int i = 0; i < workerCount; i++)
			{
				int first = i * perThreadCount;
				int last = Mathf.Min(first + perThreadCount, data.Count);
				ThreadPool.QueueUserWorkItem(delegate
				{
					List<TOut> list = new List<TOut>(perThreadCount);
					try
					{
						for (int j = first; j < last; j++)
						{
							if (exceptionThrown != null)
							{
								break;
							}
							list.Add(work(data[j]));
						}
					}
					catch (Exception ex)
					{
						exceptionThrown = ex;
					}
					lock (lockObj)
					{
						IEnumerable<TOut> enumerable2;
						if (doneItems != null)
						{
							enumerable2 = list.Concat(doneItems);
						}
						else
						{
							IEnumerable<TOut> enumerable3 = list;
							enumerable2 = enumerable3;
						}
						doneItems = enumerable2;
						int num = doneCount;
						doneCount = num + 1;
						are.Set();
					}
				});
			}
			bool isDone;
			do
			{
				are.WaitOne();
				IEnumerable<TOut> enumerable;
				lock (lockObj)
				{
					enumerable = doneItems;
					doneItems = null;
					isDone = doneCount == workerCount;
				}
				if (enumerable == null)
				{
					continue;
				}
				foreach (TOut item in enumerable)
				{
					yield return item;
				}
			}
			while (!isDone);
			if (exceptionThrown != null)
			{
				throw new TargetInvocationException("An exception was thrown inside one of the threads", exceptionThrown);
			}
		}
	}
	public static class Utility
	{
		private static bool? sreEnabled;

		public static bool CLRSupportsDynamicAssemblies => CheckSRE();

		public static Encoding UTF8NoBom { get; } = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);


		private static bool CheckSRE()
		{
			if (sreEnabled.HasValue)
			{
				return sreEnabled.Value;
			}
			try
			{
				new CustomAttributeBuilder(null, new object[0]);
			}
			catch (PlatformNotSupportedException)
			{
				sreEnabled = false;
				return sreEnabled.Value;
			}
			catch (ArgumentNullException)
			{
			}
			sreEnabled = true;
			return sreEnabled.Value;
		}

		public static bool TryDo(Action action, out Exception exception)
		{
			exception = null;
			try
			{
				action();
				return true;
			}
			catch (Exception ex)
			{
				exception = ex;
				return false;
			}
		}

		public static string CombinePaths(params string[] parts)
		{
			return parts.Aggregate(Path.Combine);
		}

		public static string ParentDirectory(string path, int levels = 1)
		{
			for (int i = 0; i < levels; i++)
			{
				path = Path.GetDirectoryName(path);
			}
			return path;
		}

		public static bool SafeParseBool(string input, bool defaultValue = false)
		{
			if (!bool.TryParse(input, out var result))
			{
				return defaultValue;
			}
			return result;
		}

		public static string ConvertToWWWFormat(string path)
		{
			return "file://" + path.Replace('\\', '/');
		}

		public static bool IsNullOrWhiteSpace(this string self)
		{
			return self?.All(char.IsWhiteSpace) ?? true;
		}

		public static IEnumerable<TNode> TopologicalSort<TNode>(IEnumerable<TNode> nodes, Func<TNode, IEnumerable<TNode>> dependencySelector)
		{
			List<TNode> sorted_list = new List<TNode>();
			HashSet<TNode> visited = new HashSet<TNode>();
			HashSet<TNode> sorted = new HashSet<TNode>();
			foreach (TNode node in nodes)
			{
				Stack<TNode> stack2 = new Stack<TNode>();
				if (!Visit(node, stack2))
				{
					throw new Exception("Cyclic Dependency:\r\n" + stack2.Select((TNode x) => $" - {x}").Aggregate((string a, string b) => a + "\r\n" + b));
				}
			}
			return sorted_list;
			bool Visit(TNode node, Stack<TNode> stack)
			{
				if (visited.Contains(node))
				{
					if (!sorted.Contains(node))
					{
						return false;
					}
				}
				else
				{
					visited.Add(node);
					stack.Push(node);
					foreach (TNode item in dependencySelector(node))
					{
						if (!Visit(item, stack))
						{
							return false;
						}
					}
					sorted.Add(node);
					sorted_list.Add(node);
					stack.Pop();
				}
				return true;
			}
		}

		private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class
		{
			assembly = null;
			List<string> list = new List<string>();
			list.Add(directory);
			list.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
			foreach (string item in list)
			{
				string text = Path.Combine(item, assemblyName.Name + ".dll");
				if (File.Exists(text))
				{
					try
					{
						assembly = loader(text);
					}
					catch (Exception)
					{
						continue;
					}
					return true;
				}
			}
			return false;
		}

		public static bool IsSubtypeOf(this TypeDefinition self, Type td)
		{
			if (((MemberReference)self).FullName == td.FullName)
			{
				return true;
			}
			if (((MemberReference)self).FullName != "System.Object")
			{
				TypeReference baseType = self.BaseType;
				return ((baseType == null) ? null : baseType.Resolve()?.IsSubtypeOf(td)).GetValueOrDefault();
			}
			return false;
		}

		public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly)
		{
			return TryResolveDllAssembly(assemblyName, directory, (Func<string, Assembly>)Assembly.LoadFile, out assembly);
		}

		public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, ReaderParameters readerParameters, out AssemblyDefinition assembly)
		{
			return TryResolveDllAssembly(assemblyName, directory, (Func<string, AssemblyDefinition>)((string s) => AssemblyDefinition.ReadAssembly(s, readerParameters)), out assembly);
		}

		public static bool TryOpenFileStream(string path, FileMode mode, out FileStream fileStream, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.Read)
		{
			try
			{
				fileStream = new FileStream(path, mode, access, share);
				return true;
			}
			catch (IOException)
			{
				fileStream = null;
				return false;
			}
		}

		public static bool TryParseAssemblyName(string fullName, out AssemblyName assemblyName)
		{
			try
			{
				assemblyName = new AssemblyName(fullName);
				return true;
			}
			catch (Exception)
			{
				assemblyName = null;
				return false;
			}
		}

		public static IEnumerable<string> GetUniqueFilesInDirectories(IEnumerable<string> directories, string pattern = "*")
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
			foreach (string directory in directories)
			{
				string[] files = Directory.GetFiles(directory, pattern);
				foreach (string text in files)
				{
					string fileName = Path.GetFileName(text);
					if (!dictionary.ContainsKey(fileName))
					{
						dictionary[fileName] = text;
					}
				}
			}
			return dictionary.Values;
		}
	}
}
namespace BepInEx.Logging
{
	public class DiskLogListener : ILogListener, IDisposable
	{
		public LogLevel DisplayedLogLevel { get; set; }

		public TextWriter LogWriter { get; protected set; }

		public Timer FlushTimer { get; protected set; }

		public bool WriteFromUnityLog { get; set; }

		public DiskLogListener(string localPath, LogLevel displayedLogLevel = LogLevel.Info, bool appendLog = false, bool includeUnityLog = false)
		{
			WriteFromUnityLog = includeUnityLog;
			DisplayedLogLevel = displayedLogLevel;
			int num = 1;
			FileStream fileStream;
			while (!Utility.TryOpenFileStream(Path.Combine(Paths.BepInExRootPath, localPath), appendLog ? FileMode.Append : FileMode.Create, out fileStream, FileAccess.Write))
			{
				if (num == 5)
				{
					Logger.LogError("Couldn't open a log file for writing. Skipping log file creation");
					return;
				}
				Logger.LogWarning("Couldn't open log file '" + localPath + "' for writing, trying another...");
				localPath = $"LogOutput.log.{num++}";
			}
			LogWriter = TextWriter.Synchronized(new StreamWriter(fileStream, Utility.UTF8NoBom));
			FlushTimer = new Timer(delegate
			{
				LogWriter?.Flush();
			}, null, 2000, 2000);
		}

		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			if ((WriteFromUnityLog || !(eventArgs.Source is UnityLogSource)) && (eventArgs.Level & DisplayedLogLevel) != 0)
			{
				LogWriter.WriteLine(eventArgs.ToString());
			}
		}

		public void Dispose()
		{
			FlushTimer?.Dispose();
			LogWriter?.Flush();
			LogWriter?.Dispose();
		}

		~DiskLogListener()
		{
			Dispose();
		}
	}
	internal class HarmonyLogSource : ILogSource, IDisposable
	{
		private static readonly ConfigEntry<LogChannel> LogChannels = ConfigFile.CoreConfig.Bind<LogChannel>("Harmony.Logger", "LogChannels", (LogChannel)24, "Specifies which Harmony log channels to listen to.\nNOTE: IL channel dumps the whole patch methods, use only when needed!");

		private static readonly Dictionary<LogChannel, LogLevel> LevelMap = new Dictionary<LogChannel, LogLevel>
		{
			[(LogChannel)2] = LogLevel.Info,
			[(LogChannel)8] = LogLevel.Warning,
			[(LogChannel)16] = LogLevel.Error,
			[(LogChannel)4] = LogLevel.Debug
		};

		public string SourceName { get; } = "HarmonyX";


		public event EventHandler<LogEventArgs> LogEvent;

		public HarmonyLogSource()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Logger.ChannelFilter = LogChannels.Value;
			Logger.MessageReceived += HandleHarmonyMessage;
		}

		private void HandleHarmonyMessage(object sender, LogEventArgs e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (LevelMap.TryGetValue(e.LogChannel, out var value))
			{
				this.LogEvent?.Invoke(this, new LogEventArgs(e.Message, value, this));
			}
		}

		public void Dispose()
		{
			Logger.MessageReceived -= HandleHarmonyMessage;
		}
	}
	public class LogEventArgs : EventArgs
	{
		public object Data { get; protected set; }

		public LogLevel Level { get; protected set; }

		public ILogSource Source { get; protected set; }

		public LogEventArgs(object data, LogLevel level, ILogSource source)
		{
			Data = data;
			Level = level;
			Source = source;
		}

		public override string ToString()
		{
			return $"[{Level,-7}:{Source.SourceName,10}] {Data}";
		}

		public string ToStringLine()
		{
			return ToString() + Environment.NewLine;
		}
	}
	public static class Logger
	{
		private sealed class LogSourceCollection : ThreadSafeCollection<ILogSource>, ICollection<ILogSource>, IEnumerable<ILogSource>, IEnumerable
		{
			public override void Add(ILogSource item)
			{
				if (item == null)
				{
					throw new ArgumentNullException("item", "Log sources cannot be null when added to the source list.");
				}
				lock (Lock)
				{
					item.LogEvent += InternalLogEvent;
					List<ILogSource> list = new List<ILogSource>(BaseList.Count + 1);
					list.AddRange(BaseList);
					list.Add(item);
					BaseList = list;
				}
			}

			public override void Clear()
			{
				if (base.Count == 0)
				{
					return;
				}
				lock (Lock)
				{
					for (int i = 0; i < BaseList.Count; i++)
					{
						BaseList[i].LogEvent -= InternalLogEvent;
					}
					BaseList = new List<ILogSource>(0);
				}
			}

			public override bool Remove(ILogSource item)
			{
				if (item == null)
				{
					return false;
				}
				lock (Lock)
				{
					bool num = base.Remove(item);
					if (num)
					{
						item.LogEvent -= InternalLogEvent;
					}
					return num;
				}
			}
		}

		private sealed class LogListenerCollection : ThreadSafeCollection<ILogListener>
		{
			public void SendLogEvent(object sender, LogEventArgs eventArgs)
			{
				List<ILogListener> baseList = BaseList;
				for (int i = 0; i < baseList.Count; i++)
				{
					baseList[i].LogEvent(sender, eventArgs);
				}
			}
		}

		private class ThreadSafeCollection<T> : ICollection<T>, IEnumerable<T>, IEnumerable where T : class
		{
			protected readonly object Lock = new object();

			protected List<T> BaseList = new List<T>(0);

			public int Count => BaseList.Count;

			public bool IsReadOnly => false;

			public IEnumerator<T> GetEnumerator()
			{
				return BaseList.GetEnumerator();
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return BaseList.GetEnumerator();
			}

			public virtual void Add(T item)
			{
				if (item == null)
				{
					throw new ArgumentNullException("item", "item can't be null");
				}
				lock (Lock)
				{
					List<T> list = new List<T>(BaseList.Count + 1);
					list.AddRange(BaseList);
					list.Add(item);
					BaseList = list;
				}
			}

			public virtual void Clear()
			{
				if (Count == 0)
				{
					return;
				}
				lock (Lock)
				{
					BaseList = new List<T>(0);
				}
			}

			public bool Contains(T item)
			{
				return BaseList.Contains(item);
			}

			public void CopyTo(T[] array, int arrayIndex)
			{
				BaseList.CopyTo(array, arrayIndex);
			}

			public virtual bool Remove(T item)
			{
				if (item == null)
				{
					return false;
				}
				lock (Lock)
				{
					List<T> list = new List<T>(BaseList.Count);
					bool result = false;
					for (int i = 0; i < BaseList.Count; i++)
					{
						T val = BaseList[i];
						if (val.Equals(item))
						{
							result = true;
						}
						else
						{
							list.Add(val);
						}
					}
					BaseList = list;
					return result;
				}
			}
		}

		private static readonly LogListenerCollection _Listeners = new LogListenerCollection();

		private static readonly ManualLogSource InternalLogSource = CreateLogSource("BepInEx");

		private static bool internalLogsInitialized;

		public static ICollection<ILogListener> Listeners => _Listeners;

		public static ICollection<ILogSource> Sources { get; } = new LogSourceCollection();


		internal static void InitializeInternalLoggers()
		{
			if (!internalLogsInitialized)
			{
				Sources.Add(new HarmonyLogSource());
				internalLogsInitialized = true;
			}
		}

		internal static void InternalLogEvent(object sender, LogEventArgs eventArgs)
		{
			_Listeners.SendLogEvent(sender, eventArgs);
		}

		internal static void Log(LogLevel level, object data)
		{
			InternalLogSource.Log(level, data);
		}

		internal static void LogFatal(object data)
		{
			Log(LogLevel.Fatal, data);
		}

		internal static void LogError(object data)
		{
			Log(LogLevel.Error, data);
		}

		internal static void LogWarning(object data)
		{
			Log(LogLevel.Warning, data);
		}

		internal static void LogMessage(object data)
		{
			Log(LogLevel.Message, data);
		}

		internal static void LogInfo(object data)
		{
			Log(LogLevel.Info, data);
		}

		internal static void LogDebug(object data)
		{
			Log(LogLevel.Debug, data);
		}

		public static ManualLogSource CreateLogSource(string sourceName)
		{
			ManualLogSource manualLogSource = new ManualLogSource(sourceName);
			Sources.Add(manualLogSource);
			return manualLogSource;
		}
	}
	[Flags]
	public enum LogLevel
	{
		None = 0,
		Fatal = 1,
		Error = 2,
		Warning = 4,
		Message = 8,
		Info = 0x10,
		Debug = 0x20,
		All = 0x3F
	}
	public static class LogLevelExtensions
	{
		public static LogLevel GetHighestLevel(this LogLevel levels)
		{
			Array values = Enum.GetValues(typeof(LogLevel));
			Array.Sort(values);
			foreach (LogLevel item in values)
			{
				if ((levels & item) != 0)
				{
					return item;
				}
			}
			return LogLevel.None;
		}

		public static ConsoleColor GetConsoleColor(this LogLevel level)
		{
			level = level.GetHighestLevel();
			return level switch
			{
				LogLevel.Fatal => ConsoleColor.Red, 
				LogLevel.Error => ConsoleColor.DarkRed, 
				LogLevel.Warning => ConsoleColor.Yellow, 
				LogLevel.Message => ConsoleColor.White, 
				LogLevel.Debug => ConsoleColor.DarkGray, 
				_ => ConsoleColor.Gray, 
			};
		}
	}
	public interface ILogListener : IDisposable
	{
		void LogEvent(object sender, LogEventArgs eventArgs);
	}
	public interface ILogSource : IDisposable
	{
		string SourceName { get; }

		event EventHandler<LogEventArgs> LogEvent;
	}
	public class ManualLogSource : ILogSource, IDisposable
	{
		public string SourceName { get; }

		public event EventHandler<LogEventArgs> LogEvent;

		public ManualLogSource(string sourceName)
		{
			SourceName = sourceName;
		}

		public void Log(LogLevel level, object data)
		{
			this.LogEvent?.Invoke(this, new LogEventArgs(data, level, this));
		}

		public void LogFatal(object data)
		{
			Log(LogLevel.Fatal, data);
		}

		public void LogError(object data)
		{
			Log(LogLevel.Error, data);
		}

		public void LogWarning(object data)
		{
			Log(LogLevel.Warning, data);
		}

		public void LogMessage(object data)
		{
			Log(LogLevel.Message, data);
		}

		public void LogInfo(object data)
		{
			Log(LogLevel.Info, data);
		}

		public void LogDebug(object data)
		{
			Log(LogLevel.Debug, data);
		}

		public void Dispose()
		{
		}
	}
	public class TraceLogSource : TraceListener
	{
		private static TraceLogSource traceListener;

		public static bool IsListening { get; protected set; }

		protected ManualLogSource LogSource { get; }

		public static ILogSource CreateSource()
		{
			if (traceListener == null)
			{
				traceListener = new TraceLogSource();
				Trace.Listeners.Add(traceListener);
				IsListening = true;
			}
			return traceListener.LogSource;
		}

		protected TraceLogSource()
		{
			LogSource = new ManualLogSource("Trace");
		}

		public override void Write(string message)
		{
			LogSource.LogInfo(message);
		}

		public override void WriteLine(string message)
		{
			LogSource.LogInfo(message);
		}

		public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
		{
			TraceEvent(eventCache, source, eventType, id, string.Format(format, args));
		}

		public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
		{
			LogSource.Log(eventType switch
			{
				TraceEventType.Critical => LogLevel.Fatal, 
				TraceEventType.Error => LogLevel.Error, 
				TraceEventType.Warning => LogLevel.Warning, 
				TraceEventType.Information => LogLevel.Info, 
				_ => LogLevel.Debug, 
			}, (message ?? "").Trim());
		}
	}
	public class ConsoleLogListener : ILogListener, IDisposable
	{
		private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind("Logging.Console", "LogLevels", LogLevel.Fatal | LogLevel.Error | LogLevel.Warning | LogLevel.Message | LogLevel.Info, "Which log levels to show in the console output.");

		internal bool WriteUnityLogs { get; set; } = true;


		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			if ((WriteUnityLogs || !(sender is UnityLogSource)) && (eventArgs.Level & ConfigConsoleDisplayedLevel.Value) != 0)
			{
				ConsoleManager.SetConsoleColor(eventArgs.Level.GetConsoleColor());
				ConsoleManager.ConsoleStream?.Write(eventArgs.ToStringLine());
				ConsoleManager.SetConsoleColor(ConsoleColor.Gray);
			}
		}

		public void Dispose()
		{
		}
	}
	public class UnityLogListener : ILogListener, IDisposable
	{
		internal static readonly Action<string> WriteStringToUnityLog;

		private ConfigEntry<bool> LogConsoleToUnity = ConfigFile.CoreConfig.Bind("Logging", "LogConsoleToUnityLog", defaultValue: false, new StringBuilder().AppendLine("If enabled, writes Standard Output messages to Unity log").AppendLine("NOTE: By default, Unity does so automatically. Only use this option if no console messages are visible in Unity log").ToString());

		static UnityLogListener()
		{
			MethodInfo[] methods = typeof(UnityLogWriter).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				try
				{
					methodInfo.Invoke(null, new object[1] { "" });
				}
				catch
				{
					continue;
				}
				WriteStringToUnityLog = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), methodInfo);
				break;
			}
			if (WriteStringToUnityLog == null)
			{
				Logger.LogError("Unable to start Unity log writer");
			}
		}

		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			if (!(eventArgs.Source is UnityLogSource) && (LogConsoleToUnity.Value || eventArgs.Source.SourceName != "Console"))
			{
				WriteStringToUnityLog?.Invoke(eventArgs.ToStringLine());
			}
		}

		public void Dispose()
		{
		}
	}
	public class UnityLogSource : ILogSource, IDisposable
	{
		private bool disposed;

		public string SourceName { get; } = "Unity Log";


		public event EventHandler<LogEventArgs> LogEvent;

		private static event EventHandler<LogEventArgs> InternalUnityLogMessage;

		public UnityLogSource()
		{
			InternalUnityLogMessage += UnityLogMessageHandler;
		}

		private void UnityLogMessageHandler(object sender, LogEventArgs eventArgs)
		{
			LogEventArgs e = new LogEventArgs(eventArgs.Data, eventArgs.Level, this);
			this.LogEvent?.Invoke(this, e);
		}

		public void Dispose()
		{
			if (!disposed)
			{
				InternalUnityLogMessage -= UnityLogMessageHandler;
				disposed = true;
			}
		}

		static UnityLogSource()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			LogCallback val = new LogCallback(OnUnityLogMessageReceived);
			EventInfo @event = typeof(Application).GetEvent("logMessageReceived", BindingFlags.Static | BindingFlags.Public);
			if ((object)@event != null)
			{
				@event.AddEventHandler(null, (Delegate?)(object)val);
				return;
			}
			typeof(Application).GetMethod("RegisterLogCallback", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { val });
		}

		private static void OnUnityLogMessageReceived(string message, string stackTrace, LogType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected I4, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			LogLevel level;
			switch ((int)type)
			{
			case 0:
			case 1:
			case 4:
				level = LogLevel.Error;
				break;
			case 2:
				level = LogLevel.Warning;
				break;
			default:
				level = LogLevel.Info;
				break;
			}
			if ((int)type == 4)
			{
				message = message + "\nStack trace:\n" + stackTrace;
			}
			UnityLogSource.InternalUnityLogMessage?.Invoke(null, new LogEventArgs(message, level, null));
		}
	}
}
namespace BepInEx.Bootstrap
{
	public static class Chainloader
	{
		private static readonly List<BaseUnityPlugin> _plugins = new List<BaseUnityPlugin>();

		private static bool? isEditor;

		private static bool _loaded = false;

		private static bool _initialized = false;

		private static readonly string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name;

		private static readonly Version CurrentAssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;

		internal static readonly ConfigEntry<bool> ConfigHideBepInExGOs = ConfigFile.CoreConfig.Bind("Chainloader", "HideManagerGameObject", defaultValue: false, new StringBuilder().AppendLine("If enabled, hides BepInEx Manager GameObject from Unity.").AppendLine("This can fix loading issues in some games that attempt to prevent BepInEx from being loaded.").AppendLine("Use this only if you know what this option means, as it can affect functionality of some older plugins.")
			.ToString());

		private static readonly ConfigEntry<bool> ConfigUnityLogging = ConfigFile.CoreConfig.Bind("Logging", "UnityLogListening", defaultValue: true, "Enables showing unity log messages in the BepInEx logging system.");

		private static readonly ConfigEntry<bool> ConfigDiskWriteUnityLog = ConfigFile.CoreConfig.Bind("Logging.Disk", "WriteUnityLog", defaultValue: false, "Include unity log messages in log file output.");

		private static readonly ConfigEntry<bool> ConfigDiskAppend = ConfigFile.CoreConfig.Bind("Logging.Disk", "AppendLog", defaultValue: false, "Appends to the log file instead of overwriting, on game startup.");

		private static readonly ConfigEntry<bool> ConfigDiskLogging = ConfigFile.CoreConfig.Bind("Logging.Disk", "Enabled", defaultValue: true, "Enables writing log messages to disk.");

		private static readonly ConfigEntry<LogLevel> ConfigDiskConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind("Logging.Disk", "LogLevels", LogLevel.Fatal | LogLevel.Error | LogLevel.Warning | LogLevel.Message | LogLevel.Info, "Which log leves are saved to the disk log output.");

		public static Dictionary<string, PluginInfo> PluginInfos { get; } = new Dictionary<string, PluginInfo>();


		private static string UnityVersion
		{
			[MethodImpl(MethodImplOptions.NoInlining)]
			get
			{
				return Application.unityVersion;
			}
		}

		private static bool IsHeadless
		{
			get
			{
				MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Application), "isBatchMode");
				if ((object)methodInfo != null)
				{
					return (bool)methodInfo.Invoke(null, null);
				}
				return SystemInfo.graphicsDeviceID == 0;
			}
		}

		internal static bool IsEditor
		{
			[MethodImpl(MethodImplOptions.NoInlining)]
			get
			{
				bool? flag = isEditor;
				if (!flag.HasValue)
				{
					bool? flag2 = (isEditor = Application.isEditor);
					return flag2.GetValueOrDefault();
				}
				return flag.GetValueOrDefault();
			}
		}

		[Obsolete("Use PluginInfos instead")]
		public static List<BaseUnityPlugin> Plugins
		{
			get
			{
				lock (_plugins)
				{
					_plugins.RemoveAll((BaseUnityPlugin x) => (Object)(object)x == (Object)null);
					return _plugins.ToList();
				}
			}
		}

		public static List<string> DependencyErrors { get; } = new List<string>();


		public static GameObject ManagerObject { get; private set; }

		private static Regex allowedGuidRegex { get; } = new Regex("^[a-zA-Z0-9\\._\\-]+$");


		public static void Initialize(string gameExePath, bool startConsole = true, ICollection<LogEventArgs> preloaderLogEvents = null)
		{
			if (!_initialized)
			{
				ThreadingHelper.Initialize();
				if (gameExePath != null)
				{
					Paths.SetExecutablePath(gameExePath);
				}
				if (ConsoleManager.ConsoleEnabled && startConsole)
				{
					ConsoleManager.CreateConsole();
					Logger.Listeners.Add(new ConsoleLogListener());
				}
				Logger.InitializeInternalLoggers();
				if (ConfigDiskLogging.Value)
				{
					Logger.Listeners.Add(new DiskLogListener("LogOutput.log", ConfigDiskConsoleDisplayedLevel.Value, ConfigDiskAppend.Value, ConfigDiskWriteUnityLog.Value));
				}
				if (!TraceLogSource.IsListening)
				{
					Logger.Sources.Add(TraceLogSource.CreateSource());
				}
				ReplayPreloaderLogs(preloaderLogEvents);
				if (ConfigUnityLogging.Value)
				{
					Logger.Sources.Add(new UnityLogSource());
				}
				if (!IsHeadless)
				{
					Logger.Listeners.Add(new UnityLogListener());
				}
				else if (Logger.Listeners.FirstOrDefault((ILogListener l) => l is ConsoleLogListener) is ConsoleLogListener consoleLogListener)
				{
					consoleLogListener.WriteUnityLogs = false;
				}
				if (PlatformHelper.Is((Platform)8))
				{
					Logger.LogInfo("Detected Unity version: v" + UnityVersion);
				}
				Logger.LogMessage("Chainloader ready");
				_initialized = true;
			}
		}

		private static void ReplayPreloaderLogs(ICollection<LogEventArgs> preloaderLogEvents)
		{
			if (preloaderLogEvents == null)
			{
				return;
			}
			UnityLogListener item = new UnityLogListener();
			Logger.Listeners.Add(item);
			ILogListener logListener = Logger.Listeners.FirstOrDefault((ILogListener logger) => logger is ConsoleLogListener);
			if (logListener != null)
			{
				Logger.Listeners.Remove(logListener);
			}
			ManualLogSource manualLogSource = Logger.CreateLogSource("Preloader");
			foreach (LogEventArgs preloaderLogEvent in preloaderLogEvents)
			{
				Logger.InternalLogEvent(manualLogSource, preloaderLogEvent);
			}
			Logger.Sources.Remove(manualLogSource);
			Logger.Listeners.Remove(item);
			if (logListener != null)
			{
				Logger.Listeners.Add(logListener);
			}
		}

		public static PluginInfo ToPluginInfo(TypeDefinition type)
		{
			if (type.IsInterface || type.IsAbstract)
			{
				return null;
			}
			try
			{
				if (!type.IsSubtypeOf(typeof(BaseUnityPlugin)))
				{
					return null;
				}
			}
			catch (AssemblyResolutionException)
			{
				return null;
			}
			BepInPlugin bepInPlugin = BepInPlugin.FromCecilType(type);
			if (bepInPlugin == null)
			{
				Logger.LogWarning("Skipping over type [" + ((MemberReference)type).FullName + "] as no metadata attribute is specified");
				return null;
			}
			if (string.IsNullOrEmpty(bepInPlugin.GUID) || !allowedGuidRegex.IsMatch(bepInPlugin.GUID))
			{
				Logger.LogWarning("Skipping type [" + ((MemberReference)type).FullName + "] because its GUID [" + bepInPlugin.GUID + "] is of an illegal format.");
				return null;
			}
			if (bepInPlugin.Version == null)
			{
				Logger.LogWarning("Skipping type [" + ((MemberReference)type).FullName + "] because its version is invalid.");
				return null;
			}
			if (bepInPlugin.Name == null)
			{
				Logger.LogWarning("Skipping type [" + ((MemberReference)type).FullName + "] because its name is null.");
				return null;
			}
			List<BepInProcess> processes = BepInProcess.FromCecilType(type);
			IEnumerable<BepInDependency> dependencies = BepInDependency.FromCecilType(type);
			IEnumerable<BepInIncompatibility> incompatibilities = BepInIncompatibility.FromCecilType(type);
			AssemblyNameReference? obj = ((IEnumerable<AssemblyNameReference>)((MemberReference)type).Module.AssemblyReferences).FirstOrDefault((Func<AssemblyNameReference, bool>)((AssemblyNameReference reference) => reference.Name == "BepInEx"));
			Version targettedBepInExVersion = ((obj != null) ? obj.Version : null) ?? new Version();
			return new PluginInfo
			{
				Metadata = bepInPlugin,
				Processes = processes,
				Dependencies = dependencies,
				Incompatibilities = incompatibilities,
				TypeName = ((MemberReference)type).FullName,
				TargettedBepInExVersion = targettedBepInExVersion
			};
		}

		private static bool HasBepinPlugins(AssemblyDefinition ass)
		{
			if (((IEnumerable<AssemblyNameReference>)ass.MainModule.AssemblyReferences).All((AssemblyNameReference r) => r.Name != CurrentAssemblyName))
			{
				return false;
			}
			if (ass.MainModule.GetTypeReferences().All((TypeReference r) => ((MemberReference)r).FullName != typeof(BepInPlugin).FullName))
			{
				return false;
			}
			return true;
		}

		private static bool PluginTargetsWrongBepin(PluginInfo pluginInfo)
		{
			Version targettedBepInExVersion = pluginInfo.TargettedBepInExVersion;
			if (targettedBepInExVersion.Major != CurrentAssemblyVersion.Major)
			{
				return true;
			}
			if (targettedBepInExVersion.Minor > CurrentAssemblyVersion.Minor)
			{
				return true;
			}
			if (targettedBepInExVersion.Minor < CurrentAssemblyVersion.Minor)
			{
				return false;
			}
			return targettedBepInExVersion.Build > CurrentAssemblyVersion.Build;
		}

		public static void Start()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			if (_loaded)
			{
				return;
			}
			if (!_initialized)
			{
				throw new InvalidOperationException("BepInEx has not been initialized. Please call Chainloader.Initialize prior to starting the chainloader instance.");
			}
			if (!Directory.Exists(Paths.PluginPath))
			{
				Directory.CreateDirectory(Paths.PluginPath);
			}
			if (!Directory.Exists(Paths.PatcherPluginPath))
			{
				Directory.CreateDirectory(Paths.PatcherPluginPath);
			}
			try
			{
				PropertyInfo property = typeof(Application).GetProperty("productName", BindingFlags.Static | BindingFlags.Public);
				if (ConsoleManager.ConsoleActive)
				{
					ConsoleManager.SetConsoleTitle($"{CurrentAssemblyName} {CurrentAssemblyVersion} - {property?.GetValue(null, null) ?? Paths.ProcessName}");
				}
				Logger.LogMessage("Chainloader started");
				ManagerObject = new GameObject("BepInEx_Manager");
				if (ConfigHideBepInExGOs.Value)
				{
					((Object)ManagerObject).hideFlags = (HideFlags)61;
				}
				Object.DontDestroyOnLoad((Object)(object)ManagerObject);
				Dictionary<string, List<PluginInfo>> dictionary = TypeLoader.FindPluginTypes(Paths.PluginPath, ToPluginInfo, HasBepinPlugins, "chainloader");
				foreach (KeyValuePair<string, List<PluginInfo>> item in dictionary)
				{
					foreach (PluginInfo item2 in item.Value)
					{
						item2.Location = item.Key;
					}
				}
				List<PluginInfo> list = dictionary.SelectMany((KeyValuePair<string, List<PluginInfo>> p) => p.Value).ToList();
				Dictionary<string, Assembly> dictionary2 = new Dictionary<string, Assembly>();
				Logger.LogInfo(string.Format("{0} plugin{1} to load", list.Count, (list.Count == 1) ? "" : "s"));
				SortedDictionary<string, IEnumerable<string>> dependencyDict = new SortedDictionary<string, IEnumerable<string>>(StringComparer.InvariantCultureIgnoreCase);
				Dictionary<string, PluginInfo> pluginsByGUID = new Dictionary<string, PluginInfo>();
				foreach (IGrouping<string, PluginInfo> item3 in from info in list
					group info by info.Metadata.GUID)
				{
					PluginInfo pluginInfo = null;
					foreach (PluginInfo item4 in item3.OrderByDescending((PluginInfo x) => x.Metadata.Version))
					{
						if (pluginInfo != null)
						{
							Logger.LogWarning($"Skipping [{item4}] because a newer version exists ({pluginInfo})");
							continue;
						}
						List<BepInProcess> list2 = item4.Processes.ToList();
						if (list2.Count != 0 && list2.All((BepInProcess x) => !string.Equals(x.ProcessName.Replace(".exe", ""), Paths.ProcessName, StringComparison.InvariantCultureIgnoreCase)))
						{
							Logger.LogWarning(string.Format("Skipping [{0}] because of process filters ({1})", item4, string.Join(", ", item4.Processes.Select((BepInProcess p) => p.ProcessName).ToArray())));
							continue;
						}
						pluginInfo = item4;
						dependencyDict[item4.Metadata.GUID] = item4.Dependencies.Select((BepInDependency d) => d.DependencyGUID);
						pluginsByGUID[item4.Metadata.GUID] = item4;
					}
				}
				foreach (PluginInfo item5 in pluginsByGUID.Values.ToList())
				{
					if (item5.Incompatibilities.Any((BepInIncompatibility incompatibility) => pluginsByGUID.ContainsKey(incompatibility.IncompatibilityGUID)))
					{
						pluginsByGUID.Remove(item5.Metadata.GUID);
						dependencyDict.Remove(item5.Metadata.GUID);
						string[] value = (from x in item5.Incompatibilities
							select x.IncompatibilityGUID into x
							where pluginsByGUID.ContainsKey(x)
							select x).ToArray();
						string text = string.Format("Could not load [{0}] because it is incompatible with: {1}", item5, string.Join(", ", value));
						DependencyErrors.Add(text);
						Logger.LogError(text);
					}
					else if (PluginTargetsWrongBepin(item5))
					{
						string text2 = $"Plugin [{item5}] targets a wrong version of BepInEx ({item5.TargettedBepInExVersion}) and might not work until you update";
						DependencyErrors.Add(text2);
						Logger.LogWarning(text2);
					}
				}
				string[] emptyDependencies = new string[0];
				IEnumerable<string> value5;
				List<string> list3 = Utility.TopologicalSort(dependencyDict.Keys, (string x) => (!dependencyDict.TryGetValue(x, out value5)) ? emptyDependencies : value5).ToList();
				HashSet<string> hashSet = new HashSet<string>();
				Dictionary<string, Version> dictionary3 = new Dictionary<string, Version>();
				foreach (string item6 in list3)
				{
					if (!pluginsByGUID.TryGetValue(item6, out var value2))
					{
						continue;
					}
					bool flag = false;
					List<BepInDependency> list4 = new List<BepInDependency>();
					foreach (BepInDependency dependency in value2.Dependencies)
					{
						if (!dictionary3.TryGetValue(dependency.DependencyGUID, out var value3) || value3 < dependency.MinimumVersion)
						{
							if (IsHardDependency(dependency))
							{
								list4.Add(dependency);
							}
						}
						else if (hashSet.Contains(dependency.DependencyGUID) && IsHardDependency(dependency))
						{
							flag = true;
							break;
						}
					}
					dictionary3.Add(item6, value2.Metadata.Version);
					if (flag)
					{
						string text3 = $"Skipping [{value2}] because it has a dependency that was not loaded. See previous errors for details.";
						DependencyErrors.Add(text3);
						Logger.LogWarning(text3);
						continue;
					}
					if (list4.Count != 0)
					{
						string text4 = string.Format("Could not load [{0}] because it has missing dependencies: {1}", value2, string.Join(", ", list4.Select((BepInDependency s) => (!IsEmptyVersion(s.MinimumVersion)) ? $"{s.DependencyGUID} (v{s.MinimumVersion} or newer)" : s.DependencyGUID).ToArray()));
						DependencyErrors.Add(text4);
						Logger.LogError(text4);
						hashSet.Add(item6);
						continue;
					}
					try
					{
						Logger.LogInfo($"Loading [{value2}]");
						if (!dictionary2.TryGetValue(value2.Location, out var value4))
						{
							value4 = (dictionary2[value2.Location] = Assembly.LoadFile(value2.Location));
						}
						PluginInfos[item6] = value2;
						value2.Instance = (BaseUnityPlugin)(object)ManagerObject.AddComponent(value4.GetType(value2.TypeName));
						_plugins.Add(value2.Instance);
					}
					catch (Exception ex)
					{
						hashSet.Add(item6);
						PluginInfos.Remove(item6);
						Logger.LogError($"Error loading [{value2}] : {ex.Message}");
						if (ex is ReflectionTypeLoadException ex2)
						{
							Logger.LogDebug(TypeLoader.TypeLoadExceptionToString(ex2));
						}
						else
						{
							Logger.LogDebug(ex);
						}
					}
				}
			}
			catch (Exception ex3)
			{
				try
				{
					ConsoleManager.CreateConsole();
				}
				catch
				{
				}
				Logger.LogFatal("Error occurred starting the game");
				Logger.LogFatal(ex3.ToString());
			}
			Logger.LogMessage("Chainloader startup complete");
			_loaded = true;
			static bool IsEmptyVersion(Version v)
			{
				if (v.Major == 0 && v.Minor == 0 && v.Build <= 0)
				{
					return v.Revision <= 0;
				}
				return false;
			}
			static bool IsHardDependency(BepInDependency dep)
			{
				return (dep.Flags & BepInDependency.DependencyFlags.HardDependency) != 0;
			}
		}
	}
	public interface ICacheable
	{
		void Save(BinaryWriter bw);

		void Load(BinaryReader br);
	}
	public class CachedAssembly<T> where T : ICacheable
	{
		public List<T> CacheItems { get; set; }

		public long Timestamp { get; set; }
	}
	public static class TypeLoader
	{
		public static readonly DefaultAssemblyResolver Resolver;

		public static readonly ReaderParameters ReaderParameters;

		[CompilerGenerated]
		private static AssemblyResolveEventHandler m_AssemblyResolve;

		private static readonly ConfigEntry<bool> EnableAssemblyCache;

		public static event AssemblyResolveEventHandler AssemblyResolve
		{
			[CompilerGenerated]
			add
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				AssemblyResolveEventHandler val = TypeLoader.m_AssemblyResolve;
				AssemblyResolveEventHandler val2;
				do
				{
					val2 = val;
					AssemblyResolveEventHandler value2 = (AssemblyResolveEventHandler)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref TypeLoader.m_AssemblyResolve, value2, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				AssemblyResolveEventHandler val = TypeLoader.m_AssemblyResolve;
				AssemblyResolveEventHandler val2;
				do
				{
					val2 = val;
					AssemblyResolveEventHandler value2 = (AssemblyResolveEventHandler)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref TypeLoader.m_AssemblyResolve, value2, val2);
				}
				while (val != val2);
			}
		}

		static TypeLoader()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_003e: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			EnableAssemblyCache = ConfigFile.CoreConfig.Bind("Caching", "EnableAssemblyCache", defaultValue: true, "Enable/disable assembly metadata cache\nEnabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.");
			Resolver = new DefaultAssemblyResolver();
			ReaderParameters = new ReaderParameters
			{
				AssemblyResolver = (IAssemblyResolver)(object)Resolver
			};
			((BaseAssemblyResolver)Resolver).ResolveFailure += (AssemblyResolveEventHandler)delegate(object sender, AssemblyNameReference reference)
			{
				if (!Utility.TryParseAssemblyName(reference.FullName, out var assemblyName))
				{
					AssemblyResolveEventHandler assemblyResolve = TypeLoader.AssemblyResolve;
					if (assemblyResolve == null)
					{
						return null;
					}
					return assemblyResolve.Invoke(sender, reference);
				}
				foreach (string item in new string[3]
				{
					Paths.BepInExAssemblyDirectory,
					Paths.PluginPath,
					Paths.PatcherPluginPath
				}.Concat(Paths.DllSearchPaths))
				{
					if (Utility.TryResolveDllAssembly(assemblyName, item, ReaderParameters, out var assembly))
					{
						return assembly;
					}
				}
				AssemblyResolveEventHandler assemblyResolve2 = TypeLoader.AssemblyResolve;
				return (assemblyResolve2 == null) ? null : assemblyResolve2.Invoke(sender, reference);
			};
		}

		public static Dictionary<string, List<T>> FindPluginTypes<T>(string directory, Func<TypeDefinition, T> typeSelector, Func<AssemblyDefinition, bool> assemblyFilter = null, string cacheName = null) where T : ICacheable, new()
		{
			Dictionary<string, List<T>> dictionary = new Dictionary<string, List<T>>();
			Dictionary<string, CachedAssembly<T>> dictionary2 = null;
			if (cacheName != null)
			{
				dictionary2 = LoadAssemblyCache<T>(cacheName);
			}
			string[] files = Directory.GetFiles(Path.GetFullPath(directory), "*.dll", SearchOption.AllDirectories);
			foreach (string text in files)
			{
				try
				{
					if (dictionary2 != null && dictionary2.TryGetValue(text, out var value) && File.GetLastWriteTimeUtc(text).Ticks == value.Timestamp)
					{
						dictionary[text] = value.CacheItems;
						continue;
					}
					AssemblyDefinition val = AssemblyDefinition.ReadAssembly(text, ReaderParameters);
					if (assemblyFilter != null && !assemblyFilter(val))
					{
						dictionary[text] = new List<T>();
						val.Dispose();
						continue;
					}
					List<T> value2 = (from t in ((IEnumerable<TypeDefinition>)val.MainModule.Types).Select(typeSelector)
						where t != null
						select t).ToList();
					dictionary[text] = value2;
					val.Dispose();
				}
				catch (BadImageFormatException ex)
				{
					Logger.LogDebug("Skipping loading " + text + " because it's not a valid .NET assembly. Full error: " + ex.Message);
				}
				catch (Exception ex2)
				{
					Logger.LogError(ex2.ToString());
				}
			}
			if (cacheName != null)
			{
				SaveAssemblyCache(cacheName, dictionary);
			}
			return dictionary;
		}

		public static Dictionary<string, CachedAssembly<T>> LoadAssemblyCache<T>(string cacheName) where T : ICacheable, new()
		{
			if (!EnableAssemblyCache.Value)
			{
				return null;
			}
			Dictionary<string, CachedAssembly<T>> dictionary = new Dictionary<string, CachedAssembly<T>>();
			try
			{
				string path = Path.Combine(Paths.CachePath, cacheName + "_typeloader.dat");
				if (!File.Exists(path))
				{
					return null;
				}
				using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
				int num = binaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					string key = binaryReader.ReadString();
					long timestamp = binaryReader.ReadInt64();
					int num2 = binaryReader.ReadInt32();
					List<T> list = new List<T>();
					for (int j = 0; j < num2; j++)
					{
						T item = new T();
						item.Load(binaryReader);
						list.Add(item);
					}
					dictionary[key] = new CachedAssembly<T>
					{
						Timestamp = timestamp,
						CacheItems = list
					};
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning("Failed to load cache \"" + cacheName + "\"; skipping loading cache. Reason: " + ex.Message + ".");
			}
			return dictionary;
		}

		public static void SaveAssemblyCache<T>(string cacheName, Dictionary<string, List<T>> entries) where T : ICacheable
		{
			if (!EnableAssemblyCache.Value)
			{
				return;
			}
			try
			{
				if (!Directory.Exists(Paths.CachePath))
				{
					Directory.CreateDirectory(Paths.CachePath);
				}
				using BinaryWriter binaryWriter = new BinaryWriter(File.OpenWrite(Path.Combine(Paths.CachePath, cacheName + "_typeloader.dat")));
				binaryWriter.Write(entries.Count);
				foreach (KeyValuePair<string, List<T>> entry in entries)
				{
					binaryWriter.Write(entry.Key);
					binaryWriter.Write(File.GetLastWriteTimeUtc(entry.Key).Ticks);
					binaryWriter.Write(entry.Value.Count);
					foreach (T item in entry.Value)
					{
						item.Save(binaryWriter);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning("Failed to save cache \"" + cacheName + "\"; skipping saving cache. Reason: " + ex.Message + ".");
			}
		}

		public static string TypeLoadExceptionToString(ReflectionTypeLoadException ex)
		{
			StringBuilder stringBuilder = new StringBuilder();
			Exception[] loaderExceptions = ex.LoaderExceptions;
			foreach (Exception ex2 in loaderExceptions)
			{
				stringBuilder.AppendLine(ex2.Message);
				if (ex2 is FileNotFoundException ex3)
				{
					if (!string.IsNullOrEmpty(ex3.FusionLog))
					{
						stringBuilder.AppendLine("Fusion Log:");
						stringBuilder.AppendLine(ex3.FusionLog);
					}
				}
				else if (ex2 is FileLoadException ex4 && !string.IsNullOrEmpty(ex4.FusionLog))
				{
					stringBuilder.AppendLine("Fusion Log:");
					stringBuilder.AppendLine(ex4.FusionLog);
				}
				stringBuilder.AppendLine();
			}
			return stringBuilder.ToString();
		}
	}
}
namespace BepInEx.ConsoleUtil
{
	internal class Kon
	{
		private struct CONSOLE_SCREEN_BUFFER_INFO
		{
			internal COORD dwSize;

			internal COORD dwCursorPosition;

			internal short wAttributes;

			internal SMALL_RECT srWindow;

			internal COORD dwMaximumWindowSize;
		}

		private struct COORD
		{
			internal short X;

			internal short Y;
		}

		private struct SMALL_RECT
		{
			internal short Left;

			internal short Top;

			internal short Right;

			internal short Bottom;
		}

		private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

		internal static IntPtr conOut = IntPtr.Zero;

		public static ConsoleColor ForegroundColor
		{
			get
			{
				return GetConsoleColor(isBackground: false);
			}
			set
			{
				SetConsoleColor(isBackground: false, value);
			}
		}

		public static ConsoleColor BackgroundColor
		{
			get
			{
				return GetConsoleColor(isBackground: true);
			}
			set
			{
				SetConsoleColor(isBackground: true, value);
			}
		}

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, short attributes);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern IntPtr GetStdHandle(int nStdHandle);

		private static short ConsoleColorToColorAttribute(sh

BepInEx/core/BepInEx.Harmony.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BepInEx.Harmony")]
[assembly: AssemblyDescription("Harmony wrapper for BepInEx")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BepInEx.Harmony")]
[assembly: AssemblyCopyright("Copyright © Bepis 2019")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("54161cfe-ff42-4dde-b161-3a49545db5cd")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace BepInEx.Harmony;

[AttributeUsage(AttributeTargets.Method)]
[Obsolete("Use HarmonyLib.ParameterByRefAttribute directly", true)]
public class ParameterByRefAttribute : ParameterByRefAttribute
{
	public int[] ParameterIndices => ((ParameterByRefAttribute)this).ParameterIndices;

	public ParameterByRefAttribute(params int[] parameterIndices)
		: base(parameterIndices)
	{
	}
}
public static class HarmonyExtensions
{
	[Obsolete("Use HarmonyLib.Harmony.PatchAll directly", true)]
	public static void PatchAll(this Harmony harmonyInstance, Type type)
	{
		HarmonyWrapper.PatchAll(type, harmonyInstance);
	}
}
public class HarmonyWrapper
{
	[Obsolete("Use HarmonyLib.Harmony.CreateAndPatchAll or HarmonyLib.Harmony.PatchAll", true)]
	public static Harmony PatchAll(Type type, Harmony harmonyInstance = null)
	{
		if (harmonyInstance == null)
		{
			return Harmony.CreateAndPatchAll(type, (string)null);
		}
		harmonyInstance.PatchAll(type);
		return harmonyInstance;
	}

	[Obsolete("Use HarmonyLib.Harmony.CreateAndPatchAll", true)]
	public static Harmony PatchAll(Type type, string harmonyInstanceId)
	{
		return Harmony.CreateAndPatchAll(type, harmonyInstanceId);
	}

	[Obsolete("Use HarmonyLib.Harmony.CreateAndPatchAll or HarmonyLib.Harmony.PatchAll", true)]
	public static Harmony PatchAll(Assembly assembly, Harmony harmonyInstance = null)
	{
		return assembly.GetTypes().Aggregate(harmonyInstance, (Harmony current, Type type) => PatchAll(type, current));
	}

	[Obsolete("Use HarmonyLib.Harmony.CreateAndPatchAll", true)]
	public static Harmony PatchAll(Assembly assembly, string harmonyInstanceId)
	{
		return Harmony.CreateAndPatchAll(assembly, harmonyInstanceId);
	}

	[Obsolete("Use HarmonyLib.Harmony.PatchAll with no arguments", true)]
	public static Harmony PatchAll(Harmony harmonyInstance = null)
	{
		return PatchAll(Assembly.GetCallingAssembly(), harmonyInstance);
	}

	[Obsolete("Use HarmonyLib.Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), ...)", true)]
	public static Harmony PatchAll(string harmonyInstanceId)
	{
		return PatchAll(Assembly.GetCallingAssembly(), harmonyInstanceId);
	}

	[Obsolete("Use HarmonyLib.Transpilers.EmitDelegate instead", true)]
	public static CodeInstruction EmitDelegate<T>(T action) where T : Delegate
	{
		return Transpilers.EmitDelegate<T>(action);
	}
}

BepInEx/core/BepInEx.Preloader.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Preloader.Patching;
using BepInEx.Preloader.RuntimeFixes;
using HarmonyLib;
using HarmonyXInterop;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.RuntimeDetour.Platforms;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BepInEx.Preloader")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BepInEx.Preloader")]
[assembly: AssemblyCopyright("Copyright ©  2019")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f7abbe07-c02f-4f7c-bf6e-c6656bf588ca")]
[assembly: AssemblyFileVersion("5.4.22.0")]
[assembly: AssemblyVersion("5.4.22.0")]
namespace BepInEx.Preloader
{
	public static class EnvVars
	{
		public static string DOORSTOP_INVOKE_DLL_PATH { get; private set; }

		public static string DOORSTOP_MANAGED_FOLDER_DIR { get; private set; }

		public static string DOORSTOP_PROCESS_PATH { get; private set; }

		public static string[] DOORSTOP_DLL_SEARCH_DIRS { get; private set; }

		internal static void LoadVars()
		{
			DOORSTOP_INVOKE_DLL_PATH = Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH");
			DOORSTOP_MANAGED_FOLDER_DIR = Environment.GetEnvironmentVariable("DOORSTOP_MANAGED_FOLDER_DIR");
			DOORSTOP_PROCESS_PATH = Environment.GetEnvironmentVariable("DOORSTOP_PROCESS_PATH");
			DOORSTOP_DLL_SEARCH_DIRS = Environment.GetEnvironmentVariable("DOORSTOP_DLL_SEARCH_DIRS")?.Split(new char[1] { Path.PathSeparator }) ?? new string[0];
		}
	}
	internal static class PreloaderRunner
	{
		private static readonly string[] CriticalAssemblies = new string[7] { "Mono.Cecil.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Pdb.dll", "Mono.Cecil.Rocks.dll", "MonoMod.Utils.dll", "MonoMod.RuntimeDetour.dll", "0Harmony.dll" };

		private static void LoadCriticalAssemblies()
		{
			string[] criticalAssemblies = CriticalAssemblies;
			foreach (string path in criticalAssemblies)
			{
				try
				{
					Assembly.LoadFile(Path.Combine(Paths.BepInExAssemblyDirectory, path));
				}
				catch (Exception)
				{
				}
			}
		}

		public static void PreloaderPreMain()
		{
			PlatformUtils.SetPlatform();
			string text = Utility.ParentDirectory(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH), 2);
			Paths.SetExecutablePath(EnvVars.DOORSTOP_PROCESS_PATH, text, EnvVars.DOORSTOP_MANAGED_FOLDER_DIR, EnvVars.DOORSTOP_DLL_SEARCH_DIRS);
			LoadCriticalAssemblies();
			AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
			AppDomain.CurrentDomain.AssemblyResolve -= Entrypoint.ResolveCurrentDirectory;
			PreloaderMain();
		}

		private static void PreloaderMain()
		{
			if (Preloader.ConfigApplyRuntimePatches.Value)
			{
				XTermFix.Apply();
				ConsoleSetOutFix.Apply();
			}
			Preloader.Run();
		}

		private static Assembly LocalResolve(object sender, ResolveEventArgs args)
		{
			AssemblyName assemblyName = default(AssemblyName);
			if (!Utility.TryParseAssemblyName(args.Name, ref assemblyName))
			{
				return null;
			}
			AssemblyName assemblyName2 = default(AssemblyName);
			var source = (from a in AppDomain.CurrentDomain.GetAssemblies()
				select new
				{
					assembly = a,
					name = (Utility.TryParseAssemblyName(a.FullName, ref assemblyName2) ? assemblyName2 : null)
				} into a
				where a.name != null && a.name.Name == assemblyName.Name
				orderby a.name.Version descending
				select a).ToList();
			Assembly assembly = (source.FirstOrDefault(a => a.name.Version == assemblyName.Version) ?? source.FirstOrDefault())?.assembly;
			if ((object)assembly != null)
			{
				return assembly;
			}
			if (Utility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, ref assembly) || Utility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, ref assembly) || Utility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, ref assembly))
			{
				return assembly;
			}
			return null;
		}
	}
	internal static class Entrypoint
	{
		private static string preloaderPath;

		public static void Main()
		{
			string text = $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log";
			try
			{
				EnvVars.LoadVars();
				text = Path.Combine(Path.GetDirectoryName(EnvVars.DOORSTOP_PROCESS_PATH) ?? ".", text);
				preloaderPath = Path.GetDirectoryName(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH));
				AppDomain.CurrentDomain.AssemblyResolve += ResolveCurrentDirectory;
				typeof(Entrypoint).Assembly.GetType("BepInEx.Preloader.PreloaderRunner")?.GetMethod("PreloaderPreMain")?.Invoke(null, null);
			}
			catch (Exception ex)
			{
				File.WriteAllText(text, ex.ToString());
			}
			finally
			{
				AppDomain.CurrentDomain.AssemblyResolve -= ResolveCurrentDirectory;
			}
		}

		internal static Assembly ResolveCurrentDirectory(object sender, ResolveEventArgs args)
		{
			AssemblyName assemblyName = new AssemblyName(args.Name);
			try
			{
				return Assembly.LoadFile(Path.Combine(preloaderPath, assemblyName.Name + ".dll"));
			}
			catch (Exception)
			{
				return null;
			}
		}
	}
	internal static class PlatformUtils
	{
		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct utsname_osx
		{
			private const int osx_utslen = 256;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string sysname;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string nodename;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string release;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string version;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string machine;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct utsname_linux
		{
			private const int linux_utslen = 65;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string sysname;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string nodename;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string release;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string version;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string machine;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
			public string domainname;
		}

		[DllImport("libc.so.6", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")]
		private static extern IntPtr uname_linux(ref utsname_linux utsname);

		[DllImport("/usr/lib/libSystem.dylib", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")]
		private static extern IntPtr uname_osx(ref utsname_osx utsname);

		public static void SetPlatform()
		{
			//IL_0002: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			Platform val = (Platform)17;
			PropertyInfo property = typeof(Environment).GetProperty("Platform", BindingFlags.Static | BindingFlags.NonPublic);
			string text = (((object)property == null) ? Environment.OSVersion.Platform.ToString() : property.GetValue(null, new object[0]).ToString());
			text = text.ToLowerInvariant();
			if (text.Contains("win"))
			{
				val = (Platform)37;
			}
			else if (text.Contains("mac") || text.Contains("osx"))
			{
				val = (Platform)73;
			}
			else if (text.Contains("lin") || text.Contains("unix"))
			{
				val = (Platform)137;
			}
			if (Is(val, (Platform)137) && Directory.Exists("/data") && File.Exists("/system/build.prop"))
			{
				val = (Platform)393;
			}
			else if (Is(val, (Platform)8) && Directory.Exists("/System/Library/AccessibilityBundles"))
			{
				val = (Platform)585;
			}
			MethodInfo methodInfo = typeof(Environment).GetProperty("Is64BitOperatingSystem")?.GetGetMethod();
			val = (Platform)(((object)methodInfo == null) ? (val | ((IntPtr.Size >= 8) ? 2 : 0)) : (val | (((bool)methodInfo.Invoke(null, new object[0])) ? 2 : 0)));
			if ((Is(val, (Platform)73) || Is(val, (Platform)137)) && (object)Type.GetType("Mono.Runtime") != null)
			{
				IntPtr intPtr;
				string machine;
				if (Is(val, (Platform)73))
				{
					utsname_osx utsname = default(utsname_osx);
					intPtr = uname_osx(ref utsname);
					machine = utsname.machine;
				}
				else
				{
					utsname_linux utsname2 = default(utsname_linux);
					intPtr = uname_linux(ref utsname2);
					machine = utsname2.machine;
				}
				if (intPtr == IntPtr.Zero && (machine.StartsWith("aarch") || machine.StartsWith("arm")))
				{
					val = (Platform)(val | 0x10000);
				}
			}
			else
			{
				typeof(object).Module.GetPEKind(out var _, out var machine2);
				if (machine2 == ImageFileMachine.ARM)
				{
					val = (Platform)(val | 0x10000);
				}
			}
			PlatformHelper.Current = val;
		}

		private static bool Is(Platform current, Platform expected)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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)
			return (Platform)(current & expected) == expected;
		}
	}
	internal static class Preloader
	{
		private enum MonoModBackend
		{
			[Description("Auto")]
			auto,
			[Description("DynamicMethod")]
			dynamicmethod,
			[Description("MethodBuilder")]
			methodbuilder,
			[Description("Cecil")]
			cecil
		}

		private static readonly ConfigEntry<string> ConfigEntrypointAssembly = ConfigFile.CoreConfig.Bind<string>("Preloader.Entrypoint", "Assembly", IsPostUnity2017 ? "UnityEngine.CoreModule.dll" : "UnityEngine.dll", "The local filename of the assembly to target.");

		private static readonly ConfigEntry<string> ConfigEntrypointType = ConfigFile.CoreConfig.Bind<string>("Preloader.Entrypoint", "Type", "Application", "The name of the type in the entrypoint assembly to search for the entrypoint method.");

		private static readonly ConfigEntry<string> ConfigEntrypointMethod = ConfigFile.CoreConfig.Bind<string>("Preloader.Entrypoint", "Method", ".cctor", "The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from.");

		internal static readonly ConfigEntry<bool> ConfigApplyRuntimePatches = ConfigFile.CoreConfig.Bind<bool>("Preloader", "ApplyRuntimePatches", true, "Enables or disables runtime patches.\nThis should always be true, unless you cannot start the game due to a Harmony related issue (such as running .NET Standard runtime) or you know what you're doing.");

		private static readonly ConfigEntry<MonoModBackend> HarmonyBackend = ConfigFile.CoreConfig.Bind<MonoModBackend>("Preloader", "HarmonyBackend", MonoModBackend.auto, "Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.\nThis setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting.");

		private static PreloaderConsoleListener PreloaderLog { get; set; }

		public static bool IsPostUnity2017 { get; } = File.Exists(Path.Combine(Paths.ManagedPath, "UnityEngine.CoreModule.dll"));


		public static void Run()
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				InitializeHarmony();
				HarmonyInteropFix.Apply();
				ConsoleManager.Initialize(false);
				AllocateConsole();
				Exception ex = default(Exception);
				Utility.TryDo((Action)delegate
				{
					if (ConfigApplyRuntimePatches.Value)
					{
						UnityPatches.Apply();
					}
				}, ref ex);
				Logger.InitializeInternalLoggers();
				Logger.Sources.Add(TraceLogSource.CreateSource());
				PreloaderLog = new PreloaderConsoleListener();
				Logger.Listeners.Add((ILogListener)(object)PreloaderLog);
				Version version = typeof(Paths).Assembly.GetName().Version;
				string text = $"BepInEx {version} - {Paths.ProcessName}";
				if (ConsoleManager.ConsoleActive)
				{
					ConsoleManager.SetConsoleTitle(text);
				}
				Logger.LogMessage((object)$"{text} ({File.GetLastWriteTime(Paths.ExecutablePath)})");
				object[] customAttributes = typeof(BuildInfoAttribute).Assembly.GetCustomAttributes(typeof(BuildInfoAttribute), inherit: false);
				if (customAttributes.Length != 0)
				{
					Logger.LogMessage((object)((BuildInfoAttribute)customAttributes[0]).Info);
				}
				Logger.LogInfo((object)("Running under Unity v" + GetUnityVersion()));
				Logger.LogInfo((object)$"CLR runtime version: {Environment.Version}");
				Logger.LogInfo((object)$"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}");
				Logger.LogInfo((object)$"System platform: {PlatformHelper.Current}");
				if (ex != null)
				{
					Logger.LogWarning((object)("Failed to apply runtime patches for Mono. See more info in the output log. Error message: " + ex.Message));
				}
				Logger.LogMessage((object)"Preloader started");
				AssemblyPatcher.AddPatcher(new PatcherPlugin
				{
					TargetDLLs = () => new string[1] { ConfigEntrypointAssembly.Value },
					Patcher = PatchEntrypoint,
					TypeName = "BepInEx.Chainloader"
				});
				Logger.Log((LogLevel)16, (object)$"Loaded 1 patcher method from [BepInEx.Preloader {version}]");
				AssemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);
				Logger.LogInfo((object)string.Format("{0} patcher plugin{1} loaded", AssemblyPatcher.PatcherPlugins.Count, (AssemblyPatcher.PatcherPlugins.Count == 1) ? "" : "s"));
				AssemblyPatcher.PatchAndLoad(Paths.DllSearchPaths);
				AssemblyPatcher.DisposePatchers();
				Logger.LogMessage((object)"Preloader finished");
				Logger.Listeners.Remove((ILogListener)(object)PreloaderLog);
				PreloaderLog.Dispose();
			}
			catch (Exception ex2)
			{
				try
				{
					Logger.LogFatal((object)"Could not run preloader!");
					Logger.LogFatal((object)ex2);
					if (!ConsoleManager.ConsoleActive)
					{
						AllocateConsole();
						Console.Write(PreloaderLog);
					}
				}
				catch
				{
				}
				string text2 = string.Empty;
				try
				{
					text2 = string.Join("\r\n", PreloaderConsoleListener.LogEvents.Select((LogEventArgs x) => ((object)x).ToString()).ToArray());
					text2 += "\r\n";
					PreloaderLog?.Dispose();
					PreloaderLog = null;
				}
				catch
				{
				}
				File.WriteAllText(Path.Combine(Paths.GameRootPath, $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"), text2 + ex2);
			}
		}

		public static void PatchEntrypoint(ref AssemblyDefinition assembly)
		{
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: 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)
			//IL_02bd: 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_0309: Unknown result type (might be due to invalid IL or missing references)
			if (((IEnumerable<AssemblyNameReference>)assembly.MainModule.AssemblyReferences).Any((AssemblyNameReference x) => x.Name.Contains("BepInEx")))
			{
				throw new Exception("BepInEx has been detected to be patched! Please unpatch before using a patchless variant!");
			}
			string entrypointType = ConfigEntrypointType.Value;
			string entrypointMethod = ConfigEntrypointMethod.Value;
			bool flag = Utility.IsNullOrWhiteSpace(entrypointMethod) || entrypointMethod == ".cctor";
			TypeDefinition val = ((IEnumerable<TypeDefinition>)assembly.MainModule.Types).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition x) => ((MemberReference)x).Name == entrypointType));
			if (val == null)
			{
				throw new Exception("The entrypoint type is invalid! Please check your config/BepInEx.cfg file");
			}
			AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(Paths.BepInExAssemblyPath);
			try
			{
				MethodDefinition val3 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)val2.MainModule.Types).First((TypeDefinition x) => ((MemberReference)x).Name == "Chainloader").Methods).First((MethodDefinition x) => ((MemberReference)x).Name == "Initialize");
				MethodDefinition val4 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)val2.MainModule.Types).First((TypeDefinition x) => ((MemberReference)x).Name == "Chainloader").Methods).First((MethodDefinition x) => ((MemberReference)x).Name == "Start");
				MethodReference val5 = assembly.MainModule.ImportReference((MethodReference)(object)val3);
				MethodReference val6 = assembly.MainModule.ImportReference((MethodReference)(object)val4);
				List<MethodDefinition> list = new List<MethodDefinition>();
				if (flag)
				{
					MethodDefinition val7 = ((IEnumerable<MethodDefinition>)val.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => m.IsConstructor && m.IsStatic));
					if (val7 == null)
					{
						val7 = new MethodDefinition(".cctor", (MethodAttributes)6289, assembly.MainModule.ImportReference(typeof(void)));
						val.Methods.Add(val7);
						ILProcessor iLProcessor = val7.Body.GetILProcessor();
						iLProcessor.Append(iLProcessor.Create(OpCodes.Ret));
					}
					list.Add(val7);
				}
				else
				{
					list.AddRange(((IEnumerable<MethodDefinition>)val.Methods).Where((MethodDefinition x) => ((MemberReference)x).Name == entrypointMethod));
				}
				if (!list.Any())
				{
					throw new Exception("The entrypoint method is invalid! Please check your config.ini");
				}
				foreach (MethodDefinition item in list)
				{
					ILProcessor iLProcessor2 = item.Body.GetILProcessor();
					Instruction val8 = ((IEnumerable<Instruction>)iLProcessor2.Body.Instructions).First();
					iLProcessor2.InsertBefore(val8, iLProcessor2.Create(OpCodes.Ldnull));
					iLProcessor2.InsertBefore(val8, iLProcessor2.Create(OpCodes.Ldc_I4_0));
					iLProcessor2.InsertBefore(val8, iLProcessor2.Create(OpCodes.Call, assembly.MainModule.ImportReference((MethodBase)AccessTools.PropertyGetter(typeof(PreloaderConsoleListener), "LogEvents"))));
					iLProcessor2.InsertBefore(val8, iLProcessor2.Create(OpCodes.Call, val5));
					iLProcessor2.InsertBefore(val8, iLProcessor2.Create(OpCodes.Call, val6));
				}
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}

		public static void AllocateConsole()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!ConsoleManager.ConsoleEnabled)
			{
				return;
			}
			try
			{
				ConsoleManager.CreateConsole();
				Logger.Listeners.Add((ILogListener)new ConsoleLogListener());
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"Failed to allocate console!");
				Logger.LogError((object)ex);
			}
		}

		public static string GetUnityVersion()
		{
			if (PlatformHelper.Is((Platform)37))
			{
				return FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion;
			}
			return "Unknown (" + (IsPostUnity2017 ? "post" : "pre") + "-2017)";
		}

		private static void InitializeHarmony()
		{
			switch (HarmonyBackend.Value)
			{
			case MonoModBackend.dynamicmethod:
			case MonoModBackend.methodbuilder:
			case MonoModBackend.cecil:
				Environment.SetEnvironmentVariable("MONOMOD_DMD_TYPE", HarmonyBackend.Value.ToString());
				break;
			default:
				throw new ArgumentOutOfRangeException("HarmonyBackend", HarmonyBackend.Value, "Unknown backend");
			case MonoModBackend.auto:
				break;
			}
		}
	}
	public class PreloaderConsoleListener : ILogListener, IDisposable
	{
		private static readonly ConfigEntry<LogLevel> ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind<LogLevel>("Logging.Console", "LogLevels", (LogLevel)31, "Which log levels to show in the console output.");

		public static List<LogEventArgs> LogEvents { get; } = new List<LogEventArgs>();


		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			//IL_0001: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			if ((eventArgs.Level & ConfigConsoleDisplayedLevel.Value) != 0)
			{
				LogEvents.Add(eventArgs);
			}
		}

		public void Dispose()
		{
		}
	}
}
namespace BepInEx.Preloader.RuntimeFixes
{
	internal static class ConsoleSetOutFix
	{
		private static LoggedTextWriter loggedTextWriter;

		internal static ManualLogSource ConsoleLogSource = Logger.CreateLogSource("Console");

		public static void Apply()
		{
			loggedTextWriter = new LoggedTextWriter
			{
				Parent = Console.Out
			};
			Console.SetOut(loggedTextWriter);
			Harmony.CreateAndPatchAll(typeof(ConsoleSetOutFix), (string)null);
		}

		[HarmonyPatch(typeof(Console), "SetOut")]
		[HarmonyPrefix]
		private static bool OnSetOut(TextWriter newOut)
		{
			loggedTextWriter.Parent = newOut;
			return false;
		}
	}
	internal class LoggedTextWriter : TextWriter
	{
		public override Encoding Encoding { get; } = Encoding.UTF8;


		public TextWriter Parent { get; set; }

		public override void Flush()
		{
			Parent.Flush();
		}

		public override void Write(string value)
		{
			ConsoleSetOutFix.ConsoleLogSource.LogInfo((object)value);
			Parent.Write(value);
		}

		public override void WriteLine(string value)
		{
			ConsoleSetOutFix.ConsoleLogSource.LogInfo((object)value);
			Parent.WriteLine(value);
		}
	}
	internal static class HarmonyInteropFix
	{
		public static void Apply()
		{
			HarmonyInterop.Initialize(Paths.CachePath);
			Harmony.CreateAndPatchAll(typeof(HarmonyInteropFix), "org.bepinex.fixes.harmonyinterop");
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Assembly), "LoadFile", new Type[] { typeof(string) })]
		private static Assembly LoadFile(string path)
		{
			return null;
		}

		[HarmonyPatch(typeof(Assembly), "LoadFile", new Type[] { typeof(string) })]
		[HarmonyPatch(typeof(Assembly), "LoadFrom", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static bool OnAssemblyLoad(ref Assembly __result, string __0)
		{
			HarmonyInterop.TryShim(__0, Paths.GameRootPath, (Action<string>)Logger.LogWarning, TypeLoader.ReaderParameters);
			__result = LoadFile(__0);
			return true;
		}
	}
	internal static class TraceFix
	{
		private static Type TraceImplType;

		private static object ListenersSyncRoot;

		private static TraceListenerCollection Listeners;

		private static PropertyInfo prop_AutoFlush;

		private static bool AutoFlush => (bool)prop_AutoFlush.GetValue(null, null);

		public static void ApplyFix()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			TraceImplType = AppDomain.CurrentDomain.GetAssemblies().First((Assembly x) => x.GetName().Name == "System").GetTypes()
				.FirstOrDefault((Type x) => x.Name == "TraceImpl");
			if ((object)TraceImplType != null)
			{
				ListenersSyncRoot = AccessTools.Property(TraceImplType, "ListenersSyncRoot").GetValue(null, null);
				Listeners = (TraceListenerCollection)AccessTools.Property(TraceImplType, "Listeners").GetValue(null, null);
				prop_AutoFlush = AccessTools.Property(TraceImplType, "AutoFlush");
				new Harmony("com.bepis.bepinex.tracefix").Patch((MethodBase)typeof(Trace).GetMethod("DoTrace", BindingFlags.Static | BindingFlags.NonPublic), new HarmonyMethod(typeof(TraceFix).GetMethod("DoTraceReplacement", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static bool DoTraceReplacement(string kind, Assembly report, string message)
		{
			string source = string.Empty;
			try
			{
				source = report.GetName().Name;
			}
			catch (MethodAccessException)
			{
			}
			TraceEventType eventType = (TraceEventType)Enum.Parse(typeof(TraceEventType), kind);
			lock (ListenersSyncRoot)
			{
				foreach (TraceListener listener in Listeners)
				{
					listener.TraceEvent(new TraceEventCache(), source, eventType, 0, message);
					if (AutoFlush)
					{
						listener.Flush();
					}
				}
			}
			return false;
		}
	}
	internal static class UnityPatches
	{
		private static Harmony HarmonyInstance { get; set; }

		public static Dictionary<string, string> AssemblyLocations { get; } = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);


		public static void Apply()
		{
			HarmonyInstance = Harmony.CreateAndPatchAll(typeof(UnityPatches), (string)null);
			try
			{
				TraceFix.ApplyFix();
			}
			catch
			{
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void GetLocation(ref string __result, Assembly __instance)
		{
			if (AssemblyLocations.TryGetValue(__instance.FullName, out var value))
			{
				__result = value;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void GetCodeBase(ref string __result, Assembly __instance)
		{
			if (AssemblyLocations.TryGetValue(__instance.FullName, out var value))
			{
				__result = "file://" + value.Replace('\\', '/');
			}
		}
	}
	internal static class XTermFix
	{
		public static int intOffset;

		public static void Apply()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			if (!PlatformHelper.Is((Platform)37) && (object)typeof(Console).Assembly.GetType("System.ConsoleDriver") != null && (object)AccessTools.Method("System.TermInfoReader:DetermineVersion", (Type[])null, (Type[])null) == null)
			{
				DetourHelper.Native = (IDetourNativePlatform)new DetourNativeX86Platform();
				Harmony val = new Harmony("com.bepinex.xtermfix");
				val.Patch((MethodBase)AccessTools.Method("System.TermInfoReader:ReadHeader", (Type[])null, (Type[])null), new HarmonyMethod(typeof(XTermFix), "ReadHeaderPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method("System.TermInfoReader:Get", new Type[1] { AccessTools.TypeByName("System.TermInfoNumbers") }, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(XTermFix), "GetTermInfoNumbersTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method("System.TermInfoReader:Get", new Type[1] { AccessTools.TypeByName("System.TermInfoStrings") }, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(XTermFix), "GetTermInfoStringsTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method("System.TermInfoReader:GetStringBytes", new Type[1] { AccessTools.TypeByName("System.TermInfoStrings") }, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(XTermFix), "GetTermInfoStringsTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				DetourHelper.Native = null;
			}
		}

		public static int GetInt32(byte[] buffer, int offset)
		{
			byte num = buffer[offset];
			int num2 = buffer[offset + 1];
			int num3 = buffer[offset + 2];
			int num4 = buffer[offset + 3];
			return num | (num2 << 8) | (num3 << 16) | (num4 << 24);
		}

		public static short GetInt16(byte[] buffer, int offset)
		{
			byte num = buffer[offset];
			int num2 = buffer[offset + 1];
			return (short)(num | (num2 << 8));
		}

		public static int GetInteger(byte[] buffer, int offset)
		{
			if (intOffset != 2)
			{
				return GetInt32(buffer, offset);
			}
			return GetInt16(buffer, offset);
		}

		public static void DetermineVersion(short magic)
		{
			switch (magic)
			{
			case 282:
				intOffset = 2;
				break;
			case 542:
				intOffset = 4;
				break;
			default:
				throw new Exception($"Unknown xterm header format: {magic}");
			}
		}

		public static bool ReadHeaderPrefix(byte[] buffer, ref int position, ref short ___boolSize, ref short ___numSize, ref short ___strOffsets)
		{
			short @int = GetInt16(buffer, position);
			position += 2;
			DetermineVersion(@int);
			position += 2;
			___boolSize = GetInt16(buffer, position);
			position += 2;
			___numSize = GetInt16(buffer, position);
			position += 2;
			___strOffsets = GetInt16(buffer, position);
			position += 2;
			position += 2;
			return false;
		}

		public static IEnumerable<CodeInstruction> GetTermInfoNumbersTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			list[31] = new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(XTermFix), "intOffset"));
			list[36] = new CodeInstruction(OpCodes.Nop, (object)null);
			list[39] = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(XTermFix), "GetInteger", (Type[])null, (Type[])null));
			return list;
		}

		public static IEnumerable<CodeInstruction> GetTermInfoStringsTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			list[32] = new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(XTermFix), "intOffset"));
			return list;
		}
	}
}
namespace BepInEx.Preloader.Patching
{
	public delegate void AssemblyPatcherDelegate(ref AssemblyDefinition assembly);
	public static class AssemblyPatcher
	{
		private const BindingFlags ALL = BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly string DumpedAssembliesPath = Utility.CombinePaths(new string[3]
		{
			Paths.BepInExRootPath,
			"DumpedAssemblies",
			Paths.ProcessName
		});

		private static readonly Dictionary<string, string> DumpedAssemblyPaths = new Dictionary<string, string>();

		private static readonly ConfigEntry<bool> ConfigDumpAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "DumpAssemblies", false, "If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.\nThis can be used by developers to inspect and debug preloader patchers.");

		private static readonly ConfigEntry<bool> ConfigLoadDumpedAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "LoadDumpedAssemblies", false, "If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.\nThis can be used to be able to load patched assemblies into debuggers like dnSpy.\nIf set to true, will override DumpAssemblies.");

		private static readonly ConfigEntry<bool> ConfigBreakBeforeLoadAssemblies = ConfigFile.CoreConfig.Bind<bool>("Preloader", "BreakBeforeLoadAssemblies", false, "If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.\nThis can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.");

		public static List<PatcherPlugin> PatcherPlugins { get; } = new List<PatcherPlugin>();


		private static IEnumerable<PatcherPlugin> PatcherPluginsSafe => PatcherPlugins.ToList();

		public static void AddPatcher(PatcherPlugin patcher)
		{
			PatcherPlugins.Add(patcher);
		}

		private static T CreateDelegate<T>(MethodInfo method) where T : class
		{
			if ((object)method == null)
			{
				return null;
			}
			return Delegate.CreateDelegate(typeof(T), method) as T;
		}

		private static PatcherPlugin ToPatcherPlugin(TypeDefinition type)
		{
			if (type.IsInterface || (type.IsAbstract && !type.IsSealed))
			{
				return null;
			}
			MethodDefinition val = ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name.Equals("get_TargetDLLs", StringComparison.InvariantCultureIgnoreCase) && m.IsPublic && m.IsStatic));
			if (val == null || ((MemberReference)((MethodReference)val).ReturnType).FullName != "System.Collections.Generic.IEnumerable`1<System.String>")
			{
				return null;
			}
			if (((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name.Equals("Patch") && m.IsPublic && m.IsStatic && ((MemberReference)((MethodReference)m).ReturnType).FullName == "System.Void" && ((MethodReference)m).Parameters.Count == 1 && (((MemberReference)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType).FullName == "Mono.Cecil.AssemblyDefinition&" || ((MemberReference)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType).FullName == "Mono.Cecil.AssemblyDefinition"))) == null)
			{
				return null;
			}
			return new PatcherPlugin
			{
				TypeName = ((MemberReference)type).FullName
			};
		}

		public static void AddPatchersFromDirectory(string directory)
		{
			if (!Directory.Exists(directory))
			{
				return;
			}
			SortedDictionary<string, PatcherPlugin> sortedDictionary = new SortedDictionary<string, PatcherPlugin>();
			foreach (KeyValuePair<string, List<PatcherPlugin>> item in TypeLoader.FindPluginTypes<PatcherPlugin>(directory, (Func<TypeDefinition, PatcherPlugin>)ToPatcherPlugin, (Func<AssemblyDefinition, bool>)null, (string)null))
			{
				string key = item.Key;
				List<PatcherPlugin> value = item.Value;
				if (value.Count == 0)
				{
					continue;
				}
				Assembly assembly = Assembly.LoadFile(key);
				foreach (PatcherPlugin item2 in value)
				{
					try
					{
						Type type = assembly.GetType(item2.TypeName);
						MethodInfo[] methods = type.GetMethods(BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						item2.Initializer = CreateDelegate<Action>(methods.FirstOrDefault((MethodInfo m) => m.Name.Equals("Initialize", StringComparison.InvariantCultureIgnoreCase) && m.GetParameters().Length == 0 && (object)m.ReturnType == typeof(void)));
						item2.Finalizer = CreateDelegate<Action>(methods.FirstOrDefault((MethodInfo m) => m.Name.Equals("Finish", StringComparison.InvariantCultureIgnoreCase) && m.GetParameters().Length == 0 && (object)m.ReturnType == typeof(void)));
						item2.TargetDLLs = CreateDelegate<Func<IEnumerable<string>>>(type.GetProperty("TargetDLLs", BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod());
						MethodInfo patcher = methods.FirstOrDefault((MethodInfo m) => m.Name.Equals("Patch", StringComparison.CurrentCultureIgnoreCase) && (object)m.ReturnType == typeof(void) && m.GetParameters().Length == 1 && ((object)m.GetParameters()[0].ParameterType == typeof(AssemblyDefinition) || (object)m.GetParameters()[0].ParameterType == typeof(AssemblyDefinition).MakeByRefType()));
						item2.Patcher = delegate(ref AssemblyDefinition pAss)
						{
							//IL_001e: Unknown result type (might be due to invalid IL or missing references)
							//IL_0024: Expected O, but got Unknown
							object[] array = new object[1] { pAss };
							patcher.Invoke(null, array);
							pAss = (AssemblyDefinition)array[0];
						};
						sortedDictionary.Add(assembly.GetName().Name + "/" + type.FullName, item2);
					}
					catch (Exception ex)
					{
						Logger.LogError((object)("Failed to load patcher [" + item2.TypeName + "]: " + ex.Message));
						if (ex is ReflectionTypeLoadException ex2)
						{
							Logger.LogDebug((object)TypeLoader.TypeLoadExceptionToString(ex2));
						}
						else
						{
							Logger.LogDebug((object)ex.ToString());
						}
					}
				}
				AssemblyName name = assembly.GetName();
				Logger.Log((LogLevel)(value.Any() ? 16 : 32), (object)string.Format("Loaded {0} patcher method{1} from [{2} {3}]", value.Count, (value.Count == 1) ? "" : "s", name.Name, name.Version));
			}
			foreach (KeyValuePair<string, PatcherPlugin> item3 in sortedDictionary)
			{
				AddPatcher(item3.Value);
			}
		}

		private static void InitializePatchers()
		{
			foreach (PatcherPlugin item in PatcherPluginsSafe)
			{
				try
				{
					item.Initializer?.Invoke();
				}
				catch (Exception arg)
				{
					Logger.LogError((object)$"Failed to run Initializer of {item.TypeName}: {arg}");
				}
			}
		}

		private static void FinalizePatching()
		{
			foreach (PatcherPlugin item in PatcherPluginsSafe)
			{
				try
				{
					item.Finalizer?.Invoke();
				}
				catch (Exception arg)
				{
					Logger.LogError((object)$"Failed to run Finalizer of {item.TypeName}: {arg}");
				}
			}
		}

		public static void DisposePatchers()
		{
			PatcherPlugins.Clear();
		}

		private static string GetAssemblyName(string fullName)
		{
			AssemblyName assemblyName = default(AssemblyName);
			if (!Utility.TryParseAssemblyName(fullName, ref assemblyName))
			{
				return fullName;
			}
			return assemblyName.Name;
		}

		public static void PatchAndLoad(params string[] directories)
		{
			Dictionary<string, AssemblyDefinition> dictionary = new Dictionary<string, AssemblyDefinition>(StringComparer.InvariantCultureIgnoreCase);
			foreach (string uniqueFilesInDirectory in Utility.GetUniqueFilesInDirectories((IEnumerable<string>)directories, "*.dll"))
			{
				AssemblyDefinition val;
				try
				{
					val = AssemblyDefinition.ReadAssembly(uniqueFilesInDirectory);
				}
				catch (BadImageFormatException)
				{
					continue;
				}
				if (((AssemblyNameReference)val.Name).Name == "System" || ((AssemblyNameReference)val.Name).Name == "mscorlib")
				{
					val.Dispose();
					continue;
				}
				if (UnityPatches.AssemblyLocations.ContainsKey(val.FullName))
				{
					Logger.LogWarning((object)("Tried to load duplicate assembly " + Path.GetFileName(uniqueFilesInDirectory) + " from Managed folder! Skipping..."));
					continue;
				}
				dictionary.Add(Path.GetFileName(uniqueFilesInDirectory), val);
				UnityPatches.AssemblyLocations.Add(val.FullName, Path.GetFullPath(uniqueFilesInDirectory));
			}
			InitializePatchers();
			HashSet<string> patchedAssemblies = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
			foreach (PatcherPlugin item in PatcherPluginsSafe)
			{
				foreach (string item2 in item.TargetDLLs())
				{
					if (!dictionary.TryGetValue(item2, out var value) || hashSet.Contains(item2))
					{
						continue;
					}
					Logger.LogInfo((object)("Patching [" + ((AssemblyNameReference)value.Name).Name + "] with [" + item.TypeName + "]"));
					try
					{
						item.Patcher?.Invoke(ref value);
					}
					catch (Exception arg)
					{
						Logger.LogError((object)$"Failed to run [{item.TypeName}] when patching [{((AssemblyNameReference)value.Name).Name}]. This assembly will not be patched. Error: {arg}");
						patchedAssemblies.Remove(item2);
						hashSet.Add(item2);
						continue;
					}
					dictionary[item2] = value;
					patchedAssemblies.Add(item2);
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					for (int i = 0; i < assemblies.Length; i++)
					{
						string assemblyName = GetAssemblyName(assemblies[i].FullName);
						if (!dictionary2.ContainsKey(assemblyName))
						{
							dictionary2[assemblyName] = item.TypeName;
						}
					}
				}
			}
			HashSet<string> patchedAssemblyNames = new HashSet<string>(from kv in dictionary
				where patchedAssemblies.Contains(kv.Key)
				select ((AssemblyNameReference)kv.Value.Name).Name, StringComparer.InvariantCultureIgnoreCase);
			List<KeyValuePair<string, string>> list = dictionary2.Where((KeyValuePair<string, string> kv) => patchedAssemblyNames.Contains(kv.Key)).ToList();
			if (list.Count != 0)
			{
				Logger.LogWarning((object)new StringBuilder().AppendLine("The following assemblies have been loaded too early and will not be patched by preloader:").AppendLine(string.Join(Environment.NewLine, list.Select((KeyValuePair<string, string> kv) => "* [" + kv.Key + "] (first loaded by [" + kv.Value + "])").ToArray())).AppendLine("Expect unexpected behavior and issues with plugins and patchers not being loaded.")
					.ToString());
			}
			DumpedAssemblyPaths.Clear();
			if (ConfigDumpAssemblies.Value || ConfigLoadDumpedAssemblies.Value)
			{
				if (!Directory.Exists(DumpedAssembliesPath))
				{
					Directory.CreateDirectory(DumpedAssembliesPath);
				}
				FileStream fileStream = default(FileStream);
				foreach (KeyValuePair<string, AssemblyDefinition> item3 in dictionary)
				{
					string key = item3.Key;
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(key);
					string extension = Path.GetExtension(key);
					AssemblyDefinition value2 = item3.Value;
					if (!patchedAssemblies.Contains(key))
					{
						continue;
					}
					int num = 0;
					string text2;
					while (true)
					{
						string text = ((num > 0) ? $"_{num}" : "");
						text2 = Path.Combine(DumpedAssembliesPath, fileNameWithoutExtension + text + extension);
						if (Utility.TryOpenFileStream(text2, FileMode.Create, ref fileStream, FileAccess.ReadWrite, FileShare.Read))
						{
							break;
						}
						num++;
					}
					value2.Write((Stream)fileStream);
					fileStream.Dispose();
					DumpedAssemblyPaths[key] = text2;
				}
			}
			if (ConfigBreakBeforeLoadAssemblies.Value)
			{
				Logger.LogInfo((object)("BepInEx is about load the following assemblies:\n" + string.Join("\n", patchedAssemblies.ToArray())));
				Logger.LogInfo((object)("The assemblies were dumped into " + DumpedAssembliesPath));
				Logger.LogInfo((object)"Load any assemblies into the debugger, set breakpoints and continue execution.");
				Debugger.Break();
			}
			foreach (KeyValuePair<string, AssemblyDefinition> item4 in dictionary)
			{
				string key2 = item4.Key;
				AssemblyDefinition value3 = item4.Value;
				if (patchedAssemblies.Contains(key2))
				{
					Load(value3, key2);
				}
				value3.Dispose();
			}
			FinalizePatching();
		}

		public static void Load(AssemblyDefinition assembly, string filename)
		{
			if (ConfigLoadDumpedAssemblies.Value && DumpedAssemblyPaths.TryGetValue(filename, out var value))
			{
				Assembly.LoadFile(value);
				return;
			}
			using MemoryStream memoryStream = new MemoryStream();
			assembly.Write((Stream)memoryStream);
			Assembly.Load(memoryStream.ToArray());
		}
	}
	public class PatcherPlugin : ICacheable
	{
		public Func<IEnumerable<string>> TargetDLLs { get; set; }

		public Action Initializer { get; set; }

		public Action Finalizer { get; set; }

		public AssemblyPatcherDelegate Patcher { get; set; }

		public string TypeName { get; set; } = string.Empty;


		public void Save(BinaryWriter bw)
		{
			bw.Write(TypeName);
		}

		public void Load(BinaryReader br)
		{
			TypeName = br.ReadString();
		}
	}
}

BepInEx/core/HarmonyXInterop.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using HarmonyLib;
using HarmonyLib.Public.Patching;
using HarmonyLib.Tools;
using Mono.Cecil;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HarmonyXInterop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HarmonyXInterop")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("160F7FE0-288D-435C-9E7E-497D3E0DE3A6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HarmonyXInterop;

internal static class DMDUtil
{
	public static MethodInfo GenerateWith<T>(this DynamicMethodDefinition dmd, object context = null) where T : DMDGenerator<T>, new()
	{
		return DMDGenerator<T>.Generate(dmd, context);
	}
}
public static class HarmonyInterop
{
	private const string BACKUP_PATH = "BepInEx_Shim_Backup";

	private static Version maxAvailableShimVersion;

	private static readonly SortedDictionary<Version, string> Assemblies = new SortedDictionary<Version, string>();

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

	private static readonly Func<MethodBase, PatchInfo, MethodInfo> UpdateWrapper = AccessTools.MethodDelegate<Func<MethodBase, PatchInfo, MethodInfo>>(AccessTools.Method(typeof(HarmonyManipulator).Assembly.GetType("HarmonyLib.PatchFunctions"), "UpdateWrapper", (Type[])null, (Type[])null), (object)null, true);

	private static readonly Action<LogChannel, Func<string>, bool> HarmonyLog = AccessTools.MethodDelegate<Action<LogChannel, Func<string>, bool>>(AccessTools.Method(typeof(Logger), "Log", (Type[])null, (Type[])null), (object)null, true);

	private static readonly Action<LogChannel, string, bool> HarmonyLogText = AccessTools.MethodDelegate<Action<LogChannel, string, bool>>(AccessTools.Method(typeof(Logger), "LogText", (Type[])null, (Type[])null), (object)null, true);

	private static readonly Dictionary<string, long> shimCache = new Dictionary<string, long>();

	private static BinaryWriter cacheWriter;

	public static void Log(int channel, Func<string> message)
	{
		HarmonyLog((LogChannel)channel, message, arg3: false);
	}

	public static void LogText(int channel, string message)
	{
		HarmonyLogText((LogChannel)channel, message, arg3: false);
	}

	public static void Initialize(string cachePath)
	{
		Directory.CreateDirectory(cachePath);
		string path = Path.Combine(cachePath, "harmony_interop_cache.dat");
		string[] files = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "0Harmony*.dll", SearchOption.AllDirectories);
		for (int i = 0; i < files.Length; i++)
		{
			AssemblyDefinition val = AssemblyDefinition.ReadAssembly(files[i]);
			try
			{
				if (((AssemblyNameReference)val.Name).Name != "0Harmony")
				{
					Assemblies.Add(((AssemblyNameReference)val.Name).Version, ((AssemblyNameReference)val.Name).Name);
					InteropAssemblyNames.Add(((AssemblyNameReference)val.Name).Name);
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
		maxAvailableShimVersion = Assemblies.LastOrDefault().Key;
		if (File.Exists(path))
		{
			try
			{
				using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
				while (true)
				{
					string key = binaryReader.ReadString();
					long value = binaryReader.ReadInt64();
					shimCache[key] = value;
				}
			}
			catch (Exception)
			{
			}
		}
		try
		{
			cacheWriter = new BinaryWriter(File.Create(path));
			foreach (KeyValuePair<string, long> item in shimCache)
			{
				cacheWriter.Write(item.Key);
				cacheWriter.Write(item.Value);
			}
			cacheWriter.Flush();
		}
		catch (IOException)
		{
		}
	}

	public static byte[] TryShim(string path, string gameRootDirectory, Action<string> logMessage = null, ReaderParameters readerParameters = null)
	{
		HashSet<string> hashSet = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
		List<string> deps;
		byte[] result = TryShimInternal(path, gameRootDirectory, logMessage, readerParameters, out deps);
		foreach (string item in deps)
		{
			hashSet.Add(item);
		}
		while (hashSet.Count != 0)
		{
			string text = hashSet.First();
			TryShimInternal(text, gameRootDirectory, logMessage, readerParameters, out deps);
			foreach (string item2 in deps)
			{
				hashSet.Add(item2);
			}
			hashSet.Remove(text);
		}
		return result;
	}

	private static bool NeedsShimming(string path, out long lastWriteTime, Action<string> logMessage = null)
	{
		lastWriteTime = 0L;
		try
		{
			if (!File.Exists(path))
			{
				return false;
			}
		}
		catch (Exception arg)
		{
			logMessage?.Invoke($"Failed to read path {path}: {arg}");
			return false;
		}
		lastWriteTime = File.GetLastWriteTimeUtc(path).Ticks;
		if (shimCache.TryGetValue(path, out var value))
		{
			return value != lastWriteTime;
		}
		return true;
	}

	private static byte[] TryShimInternal(string path, string gameRootDirectory, Action<string> logMessage, ReaderParameters readerParameters, out List<string> deps)
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		deps = new List<string>();
		if (!NeedsShimming(path, out var lastWriteTime, logMessage))
		{
			return null;
		}
		byte[] result = null;
		try
		{
			string dir = Path.GetDirectoryName(path);
			byte[] array;
			try
			{
				array = File.ReadAllBytes(path);
			}
			catch (Exception)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream(array);
			AssemblyDefinition val = AssemblyDefinition.ReadAssembly((Stream)memoryStream, (ReaderParameters)(((object)readerParameters) ?? ((object)new ReaderParameters())));
			try
			{
				deps.AddRange(from a in (IEnumerable<AssemblyNameReference>)val.MainModule.AssemblyReferences
					select Path.Combine(dir, a.Name + ".dll") into p
					where NeedsShimming(p, out var _, logMessage)
					select p);
				AssemblyNameReference harmonyRef = ((IEnumerable<AssemblyNameReference>)val.MainModule.AssemblyReferences).FirstOrDefault((Func<AssemblyNameReference, bool>)((AssemblyNameReference a) => a.Name.StartsWith("0Harmony") && !InteropAssemblyNames.Contains(a.Name)));
				if (harmonyRef != null)
				{
					KeyValuePair<Version, string> keyValuePair = Assemblies.LastOrDefault((KeyValuePair<Version, string> kv) => VersionMatches(kv.Key, harmonyRef.Version));
					if (keyValuePair.Value != null)
					{
						logMessage?.Invoke("Shimming " + path + " to use older version of Harmony (" + keyValuePair.Value + "). Please update the plugin if possible.");
						harmonyRef.Name = keyValuePair.Value;
						using MemoryStream memoryStream2 = new MemoryStream();
						val.Write((Stream)memoryStream2);
						try
						{
							string path2 = Path.Combine(gameRootDirectory, "BepInEx_Shim_Backup");
							string directoryName = Path.GetDirectoryName(Path.GetFullPath(path).Substring(gameRootDirectory.Length + 1));
							string text = Path.Combine(path2, directoryName);
							Directory.CreateDirectory(text);
							File.WriteAllBytes(Path.Combine(text, Path.GetFileName(path)), array);
							File.WriteAllBytes(path, memoryStream2.ToArray());
							lastWriteTime = File.GetLastWriteTimeUtc(path).Ticks;
						}
						catch (IOException)
						{
							lastWriteTime = 0L;
						}
						result = memoryStream2.ToArray();
					}
				}
				shimCache[path] = lastWriteTime;
				if (cacheWriter != null)
				{
					cacheWriter.Write(path);
					cacheWriter.Write(lastWriteTime);
					cacheWriter.Flush();
				}
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
		catch (Exception arg)
		{
			logMessage?.Invoke($"Failed to shim {path}: {arg}");
		}
		return result;
		static bool VersionMatches(Version cmpV, Version refV)
		{
			if (maxAvailableShimVersion != null && refV <= maxAvailableShimVersion && cmpV.Major == refV.Major && cmpV.Minor == refV.Minor)
			{
				return cmpV <= refV;
			}
			return false;
		}
	}

	public static void ApplyPatch(MethodBase target, PatchInfoWrapper add, PatchInfoWrapper remove)
	{
		PatchInfo val = PatchManager.ToPatchInfo(target);
		lock (val)
		{
			val.prefixes = Sync(add.prefixes, remove.prefixes, val.prefixes);
			val.postfixes = Sync(add.postfixes, remove.postfixes, val.postfixes);
			val.transpilers = Sync(WrapTranspilers(add.transpilers), WrapTranspilers(remove.transpilers), val.transpilers);
			val.finalizers = Sync(add.finalizers, remove.finalizers, val.finalizers);
		}
		UpdateWrapper(target, val);
		static PatchMethod[] WrapTranspilers(PatchMethod[] transpilers)
		{
			return transpilers.Select((PatchMethod p) => new PatchMethod
			{
				after = p.after,
				before = p.before,
				method = TranspilerInterop.WrapInterop(p.method),
				owner = p.owner,
				priority = p.priority
			}).ToArray();
		}
	}

	private static Patch[] Sync(PatchMethod[] add, PatchMethod[] remove, Patch[] current)
	{
		if (add.Length == 0 && remove.Length == 0)
		{
			return current;
		}
		current = current.Where((Patch p) => !remove.Any((PatchMethod r) => (object)r.method == p.PatchMethod && r.owner == p.owner)).ToArray();
		int initialIndex = current.Length;
		return current.Concat(add.Where((PatchMethod method) => method != null).Select((Func<PatchMethod, int, Patch>)((PatchMethod method, int i) => new Patch(method.ToHarmonyMethod(), i + initialIndex, method.owner)))).ToArray();
	}
}
public class PatchInfoWrapper
{
	public PatchMethod[] finalizers;

	public PatchMethod[] postfixes;

	public PatchMethod[] prefixes;

	public PatchMethod[] transpilers;
}
public class PatchMethod
{
	public string[] after;

	public string[] before;

	public MethodInfo method;

	public string owner;

	public int priority = -1;

	public HarmonyMethod ToHarmonyMethod()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		return new HarmonyMethod
		{
			after = after,
			before = before,
			method = method,
			priority = priority
		};
	}
}
public class PatchMethodComparer : IEqualityComparer<PatchMethod>
{
	public static PatchMethodComparer Instance { get; } = new PatchMethodComparer();


	public bool Equals(PatchMethod x, PatchMethod y)
	{
		if (x == y)
		{
			return true;
		}
		if (x == null)
		{
			return false;
		}
		if (y == null)
		{
			return false;
		}
		if ((object)x.GetType() != y.GetType())
		{
			return false;
		}
		if (object.Equals(x.method, y.method))
		{
			return x.owner == y.owner;
		}
		return false;
	}

	public int GetHashCode(PatchMethod obj)
	{
		return ((((object)obj.method != null) ? obj.method.GetHashCode() : 0) * 397) ^ ((obj.owner != null) ? obj.owner.GetHashCode() : 0);
	}
}
internal static class TranspilerInterop
{
	private static readonly Dictionary<OpCode, OpCode> AllJumpCodes = new Dictionary<OpCode, OpCode>
	{
		{
			OpCodes.Beq_S,
			OpCodes.Beq
		},
		{
			OpCodes.Bge_S,
			OpCodes.Bge
		},
		{
			OpCodes.Bge_Un_S,
			OpCodes.Bge_Un
		},
		{
			OpCodes.Bgt_S,
			OpCodes.Bgt
		},
		{
			OpCodes.Bgt_Un_S,
			OpCodes.Bgt_Un
		},
		{
			OpCodes.Ble_S,
			OpCodes.Ble
		},
		{
			OpCodes.Ble_Un_S,
			OpCodes.Ble_Un
		},
		{
			OpCodes.Blt_S,
			OpCodes.Blt
		},
		{
			OpCodes.Blt_Un_S,
			OpCodes.Blt_Un
		},
		{
			OpCodes.Bne_Un_S,
			OpCodes.Bne_Un
		},
		{
			OpCodes.Brfalse_S,
			OpCodes.Brfalse
		},
		{
			OpCodes.Brtrue_S,
			OpCodes.Brtrue
		},
		{
			OpCodes.Br_S,
			OpCodes.Br
		},
		{
			OpCodes.Leave_S,
			OpCodes.Leave
		}
	};

	private static readonly Dictionary<MethodInfo, MethodInfo> Wrappers = new Dictionary<MethodInfo, MethodInfo>();

	private static readonly MethodInfo ResolveToken = AccessTools.Method(typeof(MethodBase), "GetMethodFromHandle", new Type[1] { typeof(RuntimeMethodHandle) }, (Type[])null);

	private static readonly MethodInfo ApplyTranspilerMethod = AccessTools.Method(typeof(TranspilerInterop), "ApplyTranspiler", (Type[])null, (Type[])null);

	public static MethodInfo WrapInterop(MethodInfo transpiler)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		lock (Wrappers)
		{
			if (Wrappers.TryGetValue(transpiler, out var value))
			{
				return value;
			}
		}
		DynamicMethodDefinition val = new DynamicMethodDefinition("TranspilerWrapper<" + Extensions.GetID((MethodBase)transpiler, (string)null, (string)null, true, false, true) + ">", typeof(IEnumerable<CodeInstruction>), new Type[3]
		{
			typeof(IEnumerable<CodeInstruction>),
			typeof(ILGenerator),
			typeof(MethodBase)
		});
		try
		{
			ILGenerator iLGenerator = val.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldtoken, transpiler);
			iLGenerator.Emit(OpCodes.Call, ResolveToken);
			iLGenerator.Emit(OpCodes.Castclass, typeof(MethodInfo));
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			iLGenerator.Emit(OpCodes.Ldarg_2);
			iLGenerator.Emit(OpCodes.Call, ApplyTranspilerMethod);
			iLGenerator.Emit(OpCodes.Ret);
			MethodInfo methodInfo = val.GenerateWith<DMDCecilGenerator>((object)null);
			lock (Wrappers)
			{
				Wrappers[transpiler] = methodInfo;
			}
			return methodInfo;
		}
		finally
		{
			((IDisposable)val)?.Dispose();
		}
	}

	private static IEnumerable<CodeInstruction> ApplyTranspiler(MethodInfo transpiler, IEnumerable<CodeInstruction> instructions, ILGenerator generator, MethodBase method)
	{
		Dictionary<object, Dictionary<string, object>> unassignedValues;
		IEnumerable enumerable = ConvertToGeneralInstructions(transpiler, instructions, out unassignedValues);
		List<object> originalInstructions = null;
		if (unassignedValues != null)
		{
			originalInstructions = instructions.Cast<object>().ToList();
		}
		List<object> transpilerCallParameters = GetTranspilerCallParameters(generator, transpiler, method, enumerable);
		if (transpiler.Invoke(null, transpilerCallParameters.ToArray()) is IEnumerable enumerable2)
		{
			enumerable = enumerable2;
		}
		if (unassignedValues != null)
		{
			enumerable = ConvertToOurInstructions(enumerable, typeof(CodeInstruction), originalInstructions, unassignedValues);
		}
		return (enumerable as List<CodeInstruction>) ?? enumerable.Cast<CodeInstruction>().ToList();
	}

	private static OpCode ReplaceShortJumps(OpCode opcode)
	{
		using (IEnumerator<KeyValuePair<OpCode, OpCode>> enumerator = AllJumpCodes.Where((KeyValuePair<OpCode, OpCode> pair) => opcode == pair.Key).GetEnumerator())
		{
			if (enumerator.MoveNext())
			{
				return enumerator.Current.Value;
			}
		}
		return opcode;
	}

	private static object ConvertInstruction(Type type, object instruction, out Dictionary<string, object> unassigned)
	{
		Dictionary<string, object> nonExisting = new Dictionary<string, object>();
		object result = AccessTools.MakeDeepCopy(instruction, type, (Func<string, Traverse, Traverse, object>)delegate(string namePath, Traverse trvSrc, Traverse trvDest)
		{
			object value = trvSrc.GetValue();
			if (trvDest.FieldExists())
			{
				if (!(namePath == "opcode"))
				{
					return value;
				}
				return ReplaceShortJumps((OpCode)value);
			}
			nonExisting[namePath] = value;
			return null;
		}, "");
		unassigned = nonExisting;
		return result;
	}

	private static bool ShouldAddExceptionInfo(object op, int opIndex, List<object> originalInstructions, List<object> newInstructions, Dictionary<object, Dictionary<string, object>> unassignedValues)
	{
		int num = originalInstructions.IndexOf(op);
		if (num == -1)
		{
			return false;
		}
		if (!unassignedValues.TryGetValue(op, out var unassigned))
		{
			return false;
		}
		if (!unassigned.TryGetValue("blocks", out var blocksObject))
		{
			return false;
		}
		List<ExceptionBlock> blocks = blocksObject as List<ExceptionBlock>;
		if (newInstructions.Count((object instr) => instr == op) <= 1)
		{
			return true;
		}
		ExceptionBlock val = ((IEnumerable<ExceptionBlock>)blocks).FirstOrDefault((Func<ExceptionBlock, bool>)((ExceptionBlock block) => (int)block.blockType != 5));
		ExceptionBlock val2 = ((IEnumerable<ExceptionBlock>)blocks).FirstOrDefault((Func<ExceptionBlock, bool>)((ExceptionBlock block) => (int)block.blockType == 5));
		if (val != null && val2 == null)
		{
			object obj = originalInstructions.Skip(num + 1).FirstOrDefault(delegate(object instr)
			{
				if (!unassignedValues.TryGetValue(instr, out unassigned))
				{
					return false;
				}
				if (!unassigned.TryGetValue("blocks", out blocksObject))
				{
					return false;
				}
				blocks = blocksObject as List<ExceptionBlock>;
				return blocks.Any();
			});
			if (obj != null)
			{
				int num2 = num + 1;
				int num3 = num2 + originalInstructions.Skip(num2).ToList().IndexOf(obj) - 1;
				IEnumerable<object> first = originalInstructions.GetRange(num2, num3 - num2).Intersect(newInstructions);
				obj = newInstructions.Skip(opIndex + 1).FirstOrDefault(delegate(object instr)
				{
					if (!unassignedValues.TryGetValue(instr, out unassigned))
					{
						return false;
					}
					if (!unassigned.TryGetValue("blocks", out blocksObject))
					{
						return false;
					}
					blocks = blocksObject as List<ExceptionBlock>;
					return blocks.Any();
				});
				if (obj != null)
				{
					num2 = opIndex + 1;
					num3 = num2 + newInstructions.Skip(opIndex + 1).ToList().IndexOf(obj) - 1;
					List<object> range = newInstructions.GetRange(num2, num3 - num2);
					return !first.Except(range).ToList().Any();
				}
			}
		}
		if (val == null && val2 != null)
		{
			object obj2 = originalInstructions.GetRange(0, num).LastOrDefault(delegate(object instr)
			{
				if (!unassignedValues.TryGetValue(instr, out unassigned))
				{
					return false;
				}
				if (!unassigned.TryGetValue("blocks", out blocksObject))
				{
					return false;
				}
				blocks = blocksObject as List<ExceptionBlock>;
				return blocks.Any();
			});
			if (obj2 == null)
			{
				return true;
			}
			int num4 = originalInstructions.GetRange(0, num).LastIndexOf(obj2);
			int num5 = num;
			IEnumerable<object> first2 = originalInstructions.GetRange(num4, num5 - num4).Intersect(newInstructions);
			obj2 = newInstructions.GetRange(0, opIndex).LastOrDefault(delegate(object instr)
			{
				if (!unassignedValues.TryGetValue(instr, out unassigned))
				{
					return false;
				}
				if (!unassigned.TryGetValue("blocks", out blocksObject))
				{
					return false;
				}
				blocks = blocksObject as List<ExceptionBlock>;
				return blocks.Any();
			});
			if (obj2 == null)
			{
				return true;
			}
			num4 = newInstructions.GetRange(0, opIndex).LastIndexOf(obj2);
			num5 = opIndex;
			List<object> range2 = newInstructions.GetRange(num4, num5 - num4);
			return !first2.Except(range2).Any();
		}
		return true;
	}

	private static IEnumerable ConvertInstructionsAndUnassignedValues(Type type, IEnumerable enumerable, out Dictionary<object, Dictionary<string, object>> unassignedValues)
	{
		Assembly assembly = type.GetGenericTypeDefinition().Assembly;
		Type? type2 = assembly.GetType(typeof(List<>).FullName);
		Type type3 = type.GetGenericArguments()[0];
		Type type4 = type2.MakeGenericType(type3);
		object obj = Activator.CreateInstance(assembly.GetType(type4.FullName));
		MethodInfo method = obj.GetType().GetMethod("Add");
		unassignedValues = new Dictionary<object, Dictionary<string, object>>();
		foreach (object item in enumerable)
		{
			Dictionary<string, object> unassigned;
			object obj2 = ConvertInstruction(type3, item, out unassigned);
			unassignedValues.Add(obj2, unassigned);
			method.Invoke(obj, new object[1] { obj2 });
		}
		return obj as IEnumerable;
	}

	private static IEnumerable ConvertToOurInstructions(IEnumerable instructions, Type codeInstructionType, List<object> originalInstructions, Dictionary<object, Dictionary<string, object>> unassignedValues)
	{
		List<object> newInstructions = instructions.Cast<object>().ToList();
		int index = -1;
		foreach (object item in newInstructions)
		{
			index++;
			object obj = AccessTools.MakeDeepCopy(item, codeInstructionType, (Func<string, Traverse, Traverse, object>)null, "");
			if (unassignedValues.TryGetValue(item, out var value))
			{
				bool addExceptionInfo = ShouldAddExceptionInfo(item, index, originalInstructions, newInstructions, unassignedValues);
				Traverse val = Traverse.Create(obj);
				foreach (KeyValuePair<string, object> item2 in value.Where((KeyValuePair<string, object> field) => addExceptionInfo || field.Key != "blocks"))
				{
					val.Field(item2.Key).SetValue(item2.Value);
				}
			}
			yield return obj;
		}
	}

	private static bool IsCodeInstructionsParameter(Type type)
	{
		if (type.IsGenericType)
		{
			return type.GetGenericTypeDefinition().Name.StartsWith("IEnumerable", StringComparison.Ordinal);
		}
		return false;
	}

	private static IEnumerable ConvertToGeneralInstructions(MethodInfo transpiler, IEnumerable enumerable, out Dictionary<object, Dictionary<string, object>> unassignedValues)
	{
		Type type = (from p in transpiler.GetParameters()
			select p.ParameterType).FirstOrDefault((Type t) => IsCodeInstructionsParameter(t));
		if ((object)type == null)
		{
			unassignedValues = new Dictionary<object, Dictionary<string, object>>();
			return enumerable;
		}
		if ((object)type != typeof(IEnumerable<CodeInstruction>))
		{
			return ConvertInstructionsAndUnassignedValues(type, enumerable, out unassignedValues);
		}
		unassignedValues = null;
		return (enumerable as IList<CodeInstruction>) ?? ((enumerable as IEnumerable<CodeInstruction>) ?? enumerable.Cast<CodeInstruction>()).ToList();
	}

	private static List<object> GetTranspilerCallParameters(ILGenerator generator, MethodInfo transpiler, MethodBase method, IEnumerable instructions)
	{
		List<object> parameter = new List<object>();
		CollectionExtensions.Do<Type>(from param in transpiler.GetParameters()
			select param.ParameterType, (Action<Type>)delegate(Type type)
		{
			if (type.IsAssignableFrom(typeof(ILGenerator)))
			{
				parameter.Add(generator);
			}
			else if (type.IsAssignableFrom(typeof(MethodBase)))
			{
				parameter.Add(method);
			}
			else if (IsCodeInstructionsParameter(type))
			{
				parameter.Add(instructions);
			}
		});
		return parameter;
	}
}

BepInEx/core/Mono.Cecil.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using Mono.Collections.Generic;
using Mono.Security.Cryptography;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("Mono.Cecil")]
[assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("0.10.4.0")]
[assembly: AssemblyInformationalVersion("0.10.4.0")]
[assembly: AssemblyTitle("Mono.Cecil")]
[assembly: Guid("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")]
[assembly: InternalsVisibleTo("Mono.Cecil.Pdb, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")]
[assembly: InternalsVisibleTo("Mono.Cecil.Mdb, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")]
[assembly: InternalsVisibleTo("Mono.Cecil.Rocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")]
[assembly: InternalsVisibleTo("Mono.Cecil.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf")]
[assembly: AssemblyVersion("0.10.4.0")]
internal static class Consts
{
	public const string AssemblyName = "Mono.Cecil";

	public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf";
}
namespace Mono
{
	internal static class Disposable
	{
		public static Disposable<T> Owned<T>(T value) where T : class, IDisposable
		{
			return new Disposable<T>(value, owned: true);
		}

		public static Disposable<T> NotOwned<T>(T value) where T : class, IDisposable
		{
			return new Disposable<T>(value, owned: false);
		}
	}
	internal struct Disposable<T> : IDisposable where T : class, IDisposable
	{
		internal readonly T value;

		private readonly bool owned;

		public Disposable(T value, bool owned)
		{
			this.value = value;
			this.owned = owned;
		}

		public void Dispose()
		{
			if (value != null && owned)
			{
				value.Dispose();
			}
		}
	}
	internal static class Empty<T>
	{
		public static readonly T[] Array = new T[0];
	}
	internal class ArgumentNullOrEmptyException : ArgumentException
	{
		public ArgumentNullOrEmptyException(string paramName)
			: base("Argument null or empty", paramName)
		{
		}
	}
	internal class MergeSort<T>
	{
		private readonly T[] elements;

		private readonly T[] buffer;

		private readonly IComparer<T> comparer;

		private MergeSort(T[] elements, IComparer<T> comparer)
		{
			this.elements = elements;
			buffer = new T[elements.Length];
			Array.Copy(this.elements, buffer, elements.Length);
			this.comparer = comparer;
		}

		public static void Sort(T[] source, IComparer<T> comparer)
		{
			Sort(source, 0, source.Length, comparer);
		}

		public static void Sort(T[] source, int start, int length, IComparer<T> comparer)
		{
			new MergeSort<T>(source, comparer).Sort(start, length);
		}

		private void Sort(int start, int length)
		{
			TopDownSplitMerge(buffer, elements, start, length);
		}

		private void TopDownSplitMerge(T[] a, T[] b, int start, int end)
		{
			if (end - start >= 2)
			{
				int num = (end + start) / 2;
				TopDownSplitMerge(b, a, start, num);
				TopDownSplitMerge(b, a, num, end);
				TopDownMerge(a, b, start, num, end);
			}
		}

		private void TopDownMerge(T[] a, T[] b, int start, int middle, int end)
		{
			int num = start;
			int num2 = middle;
			for (int i = start; i < end; i++)
			{
				if (num < middle && (num2 >= end || comparer.Compare(a[num], a[num2]) <= 0))
				{
					b[i] = a[num++];
				}
				else
				{
					b[i] = a[num2++];
				}
			}
		}
	}
	internal static class TypeExtensions
	{
		public static TypeCode GetTypeCode(this Type type)
		{
			return Type.GetTypeCode(type);
		}

		public static Assembly Assembly(this Type type)
		{
			return type.Assembly;
		}

		public static MethodBase DeclaringMethod(this Type type)
		{
			return type.DeclaringMethod;
		}

		public static Type[] GetGenericArguments(this Type type)
		{
			return type.GetGenericArguments();
		}

		public static bool IsGenericType(this Type type)
		{
			return type.IsGenericType;
		}

		public static bool IsGenericTypeDefinition(this Type type)
		{
			return type.IsGenericTypeDefinition;
		}

		public static bool IsValueType(this Type type)
		{
			return type.IsValueType;
		}
	}
}
namespace Mono.Security.Cryptography
{
	internal static class CryptoConvert
	{
		private static int ToInt32LE(byte[] bytes, int offset)
		{
			return (bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset];
		}

		private static uint ToUInt32LE(byte[] bytes, int offset)
		{
			return (uint)((bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset]);
		}

		private static byte[] Trim(byte[] array)
		{
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] != 0)
				{
					byte[] array2 = new byte[array.Length - i];
					Buffer.BlockCopy(array, i, array2, 0, array2.Length);
					return array2;
				}
			}
			return null;
		}

		private static RSA FromCapiPrivateKeyBlob(byte[] blob, int offset)
		{
			RSAParameters parameters = default(RSAParameters);
			try
			{
				if (blob[offset] != 7 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 843141970)
				{
					throw new CryptographicException("Invalid blob header");
				}
				int num = ToInt32LE(blob, offset + 12);
				byte[] array = new byte[4];
				Buffer.BlockCopy(blob, offset + 16, array, 0, 4);
				Array.Reverse((Array)array);
				parameters.Exponent = Trim(array);
				int num2 = offset + 20;
				int num3 = num >> 3;
				parameters.Modulus = new byte[num3];
				Buffer.BlockCopy(blob, num2, parameters.Modulus, 0, num3);
				Array.Reverse((Array)parameters.Modulus);
				num2 += num3;
				int num4 = num3 >> 1;
				parameters.P = new byte[num4];
				Buffer.BlockCopy(blob, num2, parameters.P, 0, num4);
				Array.Reverse((Array)parameters.P);
				num2 += num4;
				parameters.Q = new byte[num4];
				Buffer.BlockCopy(blob, num2, parameters.Q, 0, num4);
				Array.Reverse((Array)parameters.Q);
				num2 += num4;
				parameters.DP = new byte[num4];
				Buffer.BlockCopy(blob, num2, parameters.DP, 0, num4);
				Array.Reverse((Array)parameters.DP);
				num2 += num4;
				parameters.DQ = new byte[num4];
				Buffer.BlockCopy(blob, num2, parameters.DQ, 0, num4);
				Array.Reverse((Array)parameters.DQ);
				num2 += num4;
				parameters.InverseQ = new byte[num4];
				Buffer.BlockCopy(blob, num2, parameters.InverseQ, 0, num4);
				Array.Reverse((Array)parameters.InverseQ);
				num2 += num4;
				parameters.D = new byte[num3];
				if (num2 + num3 + offset <= blob.Length)
				{
					Buffer.BlockCopy(blob, num2, parameters.D, 0, num3);
					Array.Reverse((Array)parameters.D);
				}
			}
			catch (Exception inner)
			{
				throw new CryptographicException("Invalid blob.", inner);
			}
			RSA rSA = null;
			try
			{
				rSA = RSA.Create();
				rSA.ImportParameters(parameters);
			}
			catch (CryptographicException)
			{
				bool flag = false;
				try
				{
					rSA = new RSACryptoServiceProvider(new CspParameters
					{
						Flags = CspProviderFlags.UseMachineKeyStore
					});
					rSA.ImportParameters(parameters);
				}
				catch
				{
					flag = true;
				}
				if (flag)
				{
					throw;
				}
			}
			return rSA;
		}

		private static RSA FromCapiPublicKeyBlob(byte[] blob, int offset)
		{
			try
			{
				if (blob[offset] != 6 || blob[offset + 1] != 2 || blob[offset + 2] != 0 || blob[offset + 3] != 0 || ToUInt32LE(blob, offset + 8) != 826364754)
				{
					throw new CryptographicException("Invalid blob header");
				}
				int num = ToInt32LE(blob, offset + 12);
				RSAParameters parameters = new RSAParameters
				{
					Exponent = new byte[3]
				};
				parameters.Exponent[0] = blob[offset + 18];
				parameters.Exponent[1] = blob[offset + 17];
				parameters.Exponent[2] = blob[offset + 16];
				int srcOffset = offset + 20;
				int num2 = num >> 3;
				parameters.Modulus = new byte[num2];
				Buffer.BlockCopy(blob, srcOffset, parameters.Modulus, 0, num2);
				Array.Reverse((Array)parameters.Modulus);
				RSA rSA = null;
				try
				{
					rSA = RSA.Create();
					rSA.ImportParameters(parameters);
				}
				catch (CryptographicException)
				{
					rSA = new RSACryptoServiceProvider(new CspParameters
					{
						Flags = CspProviderFlags.UseMachineKeyStore
					});
					rSA.ImportParameters(parameters);
				}
				return rSA;
			}
			catch (Exception inner)
			{
				throw new CryptographicException("Invalid blob.", inner);
			}
		}

		public static RSA FromCapiKeyBlob(byte[] blob)
		{
			return FromCapiKeyBlob(blob, 0);
		}

		public static RSA FromCapiKeyBlob(byte[] blob, int offset)
		{
			if (blob == null)
			{
				throw new ArgumentNullException("blob");
			}
			if (offset >= blob.Length)
			{
				throw new ArgumentException("blob is too small.");
			}
			switch (blob[offset])
			{
			case 0:
				if (blob[offset + 12] == 6)
				{
					return FromCapiPublicKeyBlob(blob, offset + 12);
				}
				break;
			case 6:
				return FromCapiPublicKeyBlob(blob, offset);
			case 7:
				return FromCapiPrivateKeyBlob(blob, offset);
			}
			throw new CryptographicException("Unknown blob format.");
		}
	}
}
namespace Mono.Collections.Generic
{
	public class Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection
	{
		public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
		{
			private Collection<T> collection;

			private T current;

			private int next;

			private readonly int version;

			public T Current => current;

			object IEnumerator.Current
			{
				get
				{
					CheckState();
					if (next <= 0)
					{
						throw new InvalidOperationException();
					}
					return current;
				}
			}

			internal Enumerator(Collection<T> collection)
			{
				this = default(Enumerator);
				this.collection = collection;
				version = collection.version;
			}

			public bool MoveNext()
			{
				CheckState();
				if (next < 0)
				{
					return false;
				}
				if (next < collection.size)
				{
					current = collection.items[next++];
					return true;
				}
				next = -1;
				return false;
			}

			public void Reset()
			{
				CheckState();
				next = 0;
			}

			private void CheckState()
			{
				if (collection == null)
				{
					throw new ObjectDisposedException(GetType().FullName);
				}
				if (version != collection.version)
				{
					throw new InvalidOperationException();
				}
			}

			public void Dispose()
			{
				collection = null;
			}
		}

		internal T[] items;

		internal int size;

		private int version;

		public int Count => size;

		public T this[int index]
		{
			get
			{
				if (index >= size)
				{
					throw new ArgumentOutOfRangeException();
				}
				return items[index];
			}
			set
			{
				CheckIndex(index);
				if (index == size)
				{
					throw new ArgumentOutOfRangeException();
				}
				OnSet(value, index);
				items[index] = value;
			}
		}

		public int Capacity
		{
			get
			{
				return items.Length;
			}
			set
			{
				if (value < 0 || value < size)
				{
					throw new ArgumentOutOfRangeException();
				}
				Resize(value);
			}
		}

		bool ICollection<T>.IsReadOnly => false;

		bool IList.IsFixedSize => false;

		bool IList.IsReadOnly => false;

		object IList.this[int index]
		{
			get
			{
				return this[index];
			}
			set
			{
				CheckIndex(index);
				try
				{
					this[index] = (T)value;
					return;
				}
				catch (InvalidCastException)
				{
				}
				catch (NullReferenceException)
				{
				}
				throw new ArgumentException();
			}
		}

		int ICollection.Count => Count;

		bool ICollection.IsSynchronized => false;

		object ICollection.SyncRoot => this;

		public Collection()
		{
			items = Empty<T>.Array;
		}

		public Collection(int capacity)
		{
			if (capacity < 0)
			{
				throw new ArgumentOutOfRangeException();
			}
			items = new T[capacity];
		}

		public Collection(ICollection<T> items)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			this.items = new T[items.Count];
			items.CopyTo(this.items, 0);
			size = this.items.Length;
		}

		public void Add(T item)
		{
			if (size == items.Length)
			{
				Grow(1);
			}
			OnAdd(item, size);
			items[size++] = item;
			version++;
		}

		public bool Contains(T item)
		{
			return IndexOf(item) != -1;
		}

		public int IndexOf(T item)
		{
			return Array.IndexOf(items, item, 0, size);
		}

		public void Insert(int index, T item)
		{
			CheckIndex(index);
			if (size == items.Length)
			{
				Grow(1);
			}
			OnInsert(item, index);
			Shift(index, 1);
			items[index] = item;
			version++;
		}

		public void RemoveAt(int index)
		{
			if (index < 0 || index >= size)
			{
				throw new ArgumentOutOfRangeException();
			}
			T item = items[index];
			OnRemove(item, index);
			Shift(index, -1);
			version++;
		}

		public bool Remove(T item)
		{
			int num = IndexOf(item);
			if (num == -1)
			{
				return false;
			}
			OnRemove(item, num);
			Shift(num, -1);
			version++;
			return true;
		}

		public void Clear()
		{
			OnClear();
			Array.Clear(items, 0, size);
			size = 0;
			version++;
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			Array.Copy(items, 0, array, arrayIndex, size);
		}

		public T[] ToArray()
		{
			T[] array = new T[size];
			Array.Copy(items, 0, array, 0, size);
			return array;
		}

		private void CheckIndex(int index)
		{
			if (index < 0 || index > size)
			{
				throw new ArgumentOutOfRangeException();
			}
		}

		private void Shift(int start, int delta)
		{
			if (delta < 0)
			{
				start -= delta;
			}
			if (start < size)
			{
				Array.Copy(items, start, items, start + delta, size - start);
			}
			size += delta;
			if (delta < 0)
			{
				Array.Clear(items, size, -delta);
			}
		}

		protected virtual void OnAdd(T item, int index)
		{
		}

		protected virtual void OnInsert(T item, int index)
		{
		}

		protected virtual void OnSet(T item, int index)
		{
		}

		protected virtual void OnRemove(T item, int index)
		{
		}

		protected virtual void OnClear()
		{
		}

		internal virtual void Grow(int desired)
		{
			int num = size + desired;
			if (num > items.Length)
			{
				num = Math.Max(Math.Max(items.Length * 2, 4), num);
				Resize(num);
			}
		}

		protected void Resize(int new_size)
		{
			if (new_size != size)
			{
				if (new_size < size)
				{
					throw new ArgumentOutOfRangeException();
				}
				items = items.Resize(new_size);
			}
		}

		int IList.Add(object value)
		{
			try
			{
				Add((T)value);
				return size - 1;
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			throw new ArgumentException();
		}

		void IList.Clear()
		{
			Clear();
		}

		bool IList.Contains(object value)
		{
			return ((IList)this).IndexOf(value) > -1;
		}

		int IList.IndexOf(object value)
		{
			try
			{
				return IndexOf((T)value);
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			return -1;
		}

		void IList.Insert(int index, object value)
		{
			CheckIndex(index);
			try
			{
				Insert(index, (T)value);
				return;
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			throw new ArgumentException();
		}

		void IList.Remove(object value)
		{
			try
			{
				Remove((T)value);
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
		}

		void IList.RemoveAt(int index)
		{
			RemoveAt(index);
		}

		void ICollection.CopyTo(Array array, int index)
		{
			Array.Copy(items, 0, array, index, size);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new Enumerator(this);
		}

		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			return new Enumerator(this);
		}
	}
	public sealed class ReadOnlyCollection<T> : Collection<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection
	{
		private static ReadOnlyCollection<T> empty;

		public static ReadOnlyCollection<T> Empty => empty ?? (empty = new ReadOnlyCollection<T>());

		bool ICollection<T>.IsReadOnly => true;

		bool IList.IsFixedSize => true;

		bool IList.IsReadOnly => true;

		private ReadOnlyCollection()
		{
		}

		public ReadOnlyCollection(T[] array)
		{
			if (array == null)
			{
				throw new ArgumentNullException();
			}
			Initialize(array, array.Length);
		}

		public ReadOnlyCollection(Collection<T> collection)
		{
			if (collection == null)
			{
				throw new ArgumentNullException();
			}
			Initialize(collection.items, collection.size);
		}

		private void Initialize(T[] items, int size)
		{
			base.items = new T[size];
			Array.Copy(items, 0, base.items, 0, size);
			base.size = size;
		}

		internal override void Grow(int desired)
		{
			throw new InvalidOperationException();
		}

		protected override void OnAdd(T item, int index)
		{
			throw new InvalidOperationException();
		}

		protected override void OnClear()
		{
			throw new InvalidOperationException();
		}

		protected override void OnInsert(T item, int index)
		{
			throw new InvalidOperationException();
		}

		protected override void OnRemove(T item, int index)
		{
			throw new InvalidOperationException();
		}

		protected override void OnSet(T item, int index)
		{
			throw new InvalidOperationException();
		}
	}
}
namespace Mono.Cecil
{
	internal static class Mixin
	{
		public enum Argument
		{
			name,
			fileName,
			fullName,
			stream,
			type,
			method,
			field,
			parameters,
			module,
			modifierType,
			eventType,
			fieldType,
			declaringType,
			returnType,
			propertyType,
			interfaceType
		}

		public static Version ZeroVersion = new Version(0, 0, 0, 0);

		public const int NotResolvedMarker = -2;

		public const int NoDataMarker = -1;

		internal static object NoValue = new object();

		internal static object NotResolved = new object();

		public const string mscorlib = "mscorlib";

		public const string system_runtime = "System.Runtime";

		public const string system_private_corelib = "System.Private.CoreLib";

		public const string netstandard = "netstandard";

		public const int TableCount = 58;

		public const int CodedIndexCount = 14;

		public static bool IsNullOrEmpty<T>(this T[] self)
		{
			if (self != null)
			{
				return self.Length == 0;
			}
			return true;
		}

		public static bool IsNullOrEmpty<T>(this Collection<T> self)
		{
			if (self != null)
			{
				return self.size == 0;
			}
			return true;
		}

		public static T[] Resize<T>(this T[] self, int length)
		{
			Array.Resize(ref self, length);
			return self;
		}

		public static T[] Add<T>(this T[] self, T item)
		{
			if (self == null)
			{
				self = new T[1] { item };
				return self;
			}
			self = self.Resize(self.Length + 1);
			self[^1] = item;
			return self;
		}

		public static Version CheckVersion(Version version)
		{
			if (version == null)
			{
				return ZeroVersion;
			}
			if (version.Build == -1)
			{
				return new Version(version.Major, version.Minor, 0, 0);
			}
			if (version.Revision == -1)
			{
				return new Version(version.Major, version.Minor, version.Build, 0);
			}
			return version;
		}

		public static bool TryGetUniqueDocument(this MethodDebugInformation info, out Document document)
		{
			document = info.SequencePoints[0].Document;
			for (int i = 1; i < info.SequencePoints.Count; i++)
			{
				if (info.SequencePoints[i].Document != document)
				{
					return false;
				}
			}
			return true;
		}

		public static void ResolveConstant(this IConstantProvider self, ref object constant, ModuleDefinition module)
		{
			if (module == null)
			{
				constant = NoValue;
				return;
			}
			lock (module.SyncRoot)
			{
				if (constant != NotResolved)
				{
					return;
				}
				if (module.HasImage())
				{
					constant = module.Read(self, (IConstantProvider provider, MetadataReader reader) => reader.ReadConstant(provider));
				}
				else
				{
					constant = NoValue;
				}
			}
		}

		public static bool GetHasCustomAttributes(this ICustomAttributeProvider self, ModuleDefinition module)
		{
			if (module.HasImage())
			{
				return module.Read(self, (ICustomAttributeProvider provider, MetadataReader reader) => reader.HasCustomAttributes(provider));
			}
			return false;
		}

		public static Collection<CustomAttribute> GetCustomAttributes(this ICustomAttributeProvider self, ref Collection<CustomAttribute> variable, ModuleDefinition module)
		{
			if (!module.HasImage())
			{
				return variable = new Collection<CustomAttribute>();
			}
			return module.Read(ref variable, self, (ICustomAttributeProvider provider, MetadataReader reader) => reader.ReadCustomAttributes(provider));
		}

		public static bool ContainsGenericParameter(this IGenericInstance self)
		{
			Collection<TypeReference> genericArguments = self.GenericArguments;
			for (int i = 0; i < genericArguments.Count; i++)
			{
				if (genericArguments[i].ContainsGenericParameter)
				{
					return true;
				}
			}
			return false;
		}

		public static void GenericInstanceFullName(this IGenericInstance self, StringBuilder builder)
		{
			builder.Append("<");
			Collection<TypeReference> genericArguments = self.GenericArguments;
			for (int i = 0; i < genericArguments.Count; i++)
			{
				if (i > 0)
				{
					builder.Append(",");
				}
				builder.Append(genericArguments[i].FullName);
			}
			builder.Append(">");
		}

		public static bool GetHasGenericParameters(this IGenericParameterProvider self, ModuleDefinition module)
		{
			if (module.HasImage())
			{
				return module.Read(self, (IGenericParameterProvider provider, MetadataReader reader) => reader.HasGenericParameters(provider));
			}
			return false;
		}

		public static Collection<GenericParameter> GetGenericParameters(this IGenericParameterProvider self, ref Collection<GenericParameter> collection, ModuleDefinition module)
		{
			if (!module.HasImage())
			{
				return collection = new GenericParameterCollection(self);
			}
			return module.Read(ref collection, self, (IGenericParameterProvider provider, MetadataReader reader) => reader.ReadGenericParameters(provider));
		}

		public static bool GetHasMarshalInfo(this IMarshalInfoProvider self, ModuleDefinition module)
		{
			if (module.HasImage())
			{
				return module.Read(self, (IMarshalInfoProvider provider, MetadataReader reader) => reader.HasMarshalInfo(provider));
			}
			return false;
		}

		public static MarshalInfo GetMarshalInfo(this IMarshalInfoProvider self, ref MarshalInfo variable, ModuleDefinition module)
		{
			if (!module.HasImage())
			{
				return null;
			}
			return module.Read(ref variable, self, (IMarshalInfoProvider provider, MetadataReader reader) => reader.ReadMarshalInfo(provider));
		}

		public static bool GetAttributes(this uint self, uint attributes)
		{
			return (self & attributes) != 0;
		}

		public static uint SetAttributes(this uint self, uint attributes, bool value)
		{
			if (value)
			{
				return self | attributes;
			}
			return self & ~attributes;
		}

		public static bool GetMaskedAttributes(this uint self, uint mask, uint attributes)
		{
			return (self & mask) == attributes;
		}

		public static uint SetMaskedAttributes(this uint self, uint mask, uint attributes, bool value)
		{
			if (value)
			{
				self &= ~mask;
				return self | attributes;
			}
			return self & ~(mask & attributes);
		}

		public static bool GetAttributes(this ushort self, ushort attributes)
		{
			return (self & attributes) != 0;
		}

		public static ushort SetAttributes(this ushort self, ushort attributes, bool value)
		{
			if (value)
			{
				return (ushort)(self | attributes);
			}
			return (ushort)(self & ~attributes);
		}

		public static bool GetMaskedAttributes(this ushort self, ushort mask, uint attributes)
		{
			return (self & mask) == attributes;
		}

		public static ushort SetMaskedAttributes(this ushort self, ushort mask, uint attributes, bool value)
		{
			if (value)
			{
				self = (ushort)(self & ~mask);
				return (ushort)(self | attributes);
			}
			return (ushort)(self & ~(mask & attributes));
		}

		public static bool HasImplicitThis(this IMethodSignature self)
		{
			if (self.HasThis)
			{
				return !self.ExplicitThis;
			}
			return false;
		}

		public static void MethodSignatureFullName(this IMethodSignature self, StringBuilder builder)
		{
			builder.Append("(");
			if (self.HasParameters)
			{
				Collection<ParameterDefinition> parameters = self.Parameters;
				for (int i = 0; i < parameters.Count; i++)
				{
					ParameterDefinition parameterDefinition = parameters[i];
					if (i > 0)
					{
						builder.Append(",");
					}
					if (parameterDefinition.ParameterType.IsSentinel)
					{
						builder.Append("...,");
					}
					builder.Append(parameterDefinition.ParameterType.FullName);
				}
			}
			builder.Append(")");
		}

		public static void CheckModule(ModuleDefinition module)
		{
			if (module == null)
			{
				throw new ArgumentNullException(Argument.module.ToString());
			}
		}

		public static bool TryGetAssemblyNameReference(this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference)
		{
			Collection<AssemblyNameReference> assemblyReferences = module.AssemblyReferences;
			for (int i = 0; i < assemblyReferences.Count; i++)
			{
				AssemblyNameReference assemblyNameReference = assemblyReferences[i];
				if (Equals(name_reference, assemblyNameReference))
				{
					assembly_reference = assemblyNameReference;
					return true;
				}
			}
			assembly_reference = null;
			return false;
		}

		private static bool Equals(byte[] a, byte[] b)
		{
			if (a == b)
			{
				return true;
			}
			if (a == null)
			{
				return false;
			}
			if (a.Length != b.Length)
			{
				return false;
			}
			for (int i = 0; i < a.Length; i++)
			{
				if (a[i] != b[i])
				{
					return false;
				}
			}
			return true;
		}

		private static bool Equals<T>(T a, T b) where T : class, IEquatable<T>
		{
			if (a == b)
			{
				return true;
			}
			return a?.Equals(b) ?? false;
		}

		private static bool Equals(AssemblyNameReference a, AssemblyNameReference b)
		{
			if (a == b)
			{
				return true;
			}
			if (a.Name != b.Name)
			{
				return false;
			}
			if (!Equals(a.Version, b.Version))
			{
				return false;
			}
			if (a.Culture != b.Culture)
			{
				return false;
			}
			if (!Equals(a.PublicKeyToken, b.PublicKeyToken))
			{
				return false;
			}
			return true;
		}

		public static ParameterDefinition GetParameter(this Mono.Cecil.Cil.MethodBody self, int index)
		{
			MethodDefinition method = self.method;
			if (method.HasThis)
			{
				if (index == 0)
				{
					return self.ThisParameter;
				}
				index--;
			}
			Collection<ParameterDefinition> parameters = method.Parameters;
			if (index < 0 || index >= parameters.size)
			{
				return null;
			}
			return parameters[index];
		}

		public static VariableDefinition GetVariable(this Mono.Cecil.Cil.MethodBody self, int index)
		{
			Collection<VariableDefinition> variables = self.Variables;
			if (index < 0 || index >= variables.size)
			{
				return null;
			}
			return variables[index];
		}

		public static bool GetSemantics(this MethodDefinition self, MethodSemanticsAttributes semantics)
		{
			return (self.SemanticsAttributes & semantics) != 0;
		}

		public static void SetSemantics(this MethodDefinition self, MethodSemanticsAttributes semantics, bool value)
		{
			if (value)
			{
				self.SemanticsAttributes |= semantics;
			}
			else
			{
				self.SemanticsAttributes &= (MethodSemanticsAttributes)(ushort)(~(int)semantics);
			}
		}

		public static bool IsVarArg(this IMethodSignature self)
		{
			return self.CallingConvention == MethodCallingConvention.VarArg;
		}

		public static int GetSentinelPosition(this IMethodSignature self)
		{
			if (!self.HasParameters)
			{
				return -1;
			}
			Collection<ParameterDefinition> parameters = self.Parameters;
			for (int i = 0; i < parameters.Count; i++)
			{
				if (parameters[i].ParameterType.IsSentinel)
				{
					return i;
				}
			}
			return -1;
		}

		public static void CheckName(object name)
		{
			if (name == null)
			{
				throw new ArgumentNullException(Argument.name.ToString());
			}
		}

		public static void CheckName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentNullOrEmptyException(Argument.name.ToString());
			}
		}

		public static void CheckFileName(string fileName)
		{
			if (string.IsNullOrEmpty(fileName))
			{
				throw new ArgumentNullOrEmptyException(Argument.fileName.ToString());
			}
		}

		public static void CheckFullName(string fullName)
		{
			if (string.IsNullOrEmpty(fullName))
			{
				throw new ArgumentNullOrEmptyException(Argument.fullName.ToString());
			}
		}

		public static void CheckStream(object stream)
		{
			if (stream == null)
			{
				throw new ArgumentNullException(Argument.stream.ToString());
			}
		}

		public static void CheckWriteSeek(Stream stream)
		{
			if (!stream.CanWrite || !stream.CanSeek)
			{
				throw new ArgumentException("Stream must be writable and seekable.");
			}
		}

		public static void CheckReadSeek(Stream stream)
		{
			if (!stream.CanRead || !stream.CanSeek)
			{
				throw new ArgumentException("Stream must be readable and seekable.");
			}
		}

		public static void CheckType(object type)
		{
			if (type == null)
			{
				throw new ArgumentNullException(Argument.type.ToString());
			}
		}

		public static void CheckType(object type, Argument argument)
		{
			if (type == null)
			{
				throw new ArgumentNullException(argument.ToString());
			}
		}

		public static void CheckField(object field)
		{
			if (field == null)
			{
				throw new ArgumentNullException(Argument.field.ToString());
			}
		}

		public static void CheckMethod(object method)
		{
			if (method == null)
			{
				throw new ArgumentNullException(Argument.method.ToString());
			}
		}

		public static void CheckParameters(object parameters)
		{
			if (parameters == null)
			{
				throw new ArgumentNullException(Argument.parameters.ToString());
			}
		}

		public static uint GetTimestamp()
		{
			return (uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
		}

		public static bool HasImage(this ModuleDefinition self)
		{
			return self?.HasImage ?? false;
		}

		public static string GetFileName(this Stream self)
		{
			if (!(self is FileStream fileStream))
			{
				return string.Empty;
			}
			return Path.GetFullPath(fileStream.Name);
		}

		public static void CopyTo(this Stream self, Stream target)
		{
			byte[] array = new byte[8192];
			int count;
			while ((count = self.Read(array, 0, array.Length)) > 0)
			{
				target.Write(array, 0, count);
			}
		}

		public static TargetRuntime ParseRuntime(this string self)
		{
			if (string.IsNullOrEmpty(self))
			{
				return TargetRuntime.Net_4_0;
			}
			switch (self[1])
			{
			case '1':
				if (self[3] != '0')
				{
					return TargetRuntime.Net_1_1;
				}
				return TargetRuntime.Net_1_0;
			case '2':
				return TargetRuntime.Net_2_0;
			default:
				return TargetRuntime.Net_4_0;
			}
		}

		public static string RuntimeVersionString(this TargetRuntime runtime)
		{
			return runtime switch
			{
				TargetRuntime.Net_1_0 => "v1.0.3705", 
				TargetRuntime.Net_1_1 => "v1.1.4322", 
				TargetRuntime.Net_2_0 => "v2.0.50727", 
				_ => "v4.0.30319", 
			};
		}

		public static bool IsWindowsMetadata(this ModuleDefinition module)
		{
			return module.MetadataKind != MetadataKind.Ecma335;
		}

		public static byte[] ReadAll(this Stream self)
		{
			MemoryStream memoryStream = new MemoryStream((int)self.Length);
			byte[] array = new byte[1024];
			int count;
			while ((count = self.Read(array, 0, array.Length)) != 0)
			{
				memoryStream.Write(array, 0, count);
			}
			return memoryStream.ToArray();
		}

		public static void Read(object o)
		{
		}

		public static bool GetHasSecurityDeclarations(this ISecurityDeclarationProvider self, ModuleDefinition module)
		{
			if (module.HasImage())
			{
				return module.Read(self, (ISecurityDeclarationProvider provider, MetadataReader reader) => reader.HasSecurityDeclarations(provider));
			}
			return false;
		}

		public static Collection<SecurityDeclaration> GetSecurityDeclarations(this ISecurityDeclarationProvider self, ref Collection<SecurityDeclaration> variable, ModuleDefinition module)
		{
			if (!module.HasImage())
			{
				return variable = new Collection<SecurityDeclaration>();
			}
			return module.Read(ref variable, self, (ISecurityDeclarationProvider provider, MetadataReader reader) => reader.ReadSecurityDeclarations(provider));
		}

		public static TypeReference GetEnumUnderlyingType(this TypeDefinition self)
		{
			Collection<FieldDefinition> fields = self.Fields;
			for (int i = 0; i < fields.Count; i++)
			{
				FieldDefinition fieldDefinition = fields[i];
				if (!fieldDefinition.IsStatic)
				{
					return fieldDefinition.FieldType;
				}
			}
			throw new ArgumentException();
		}

		public static TypeDefinition GetNestedType(this TypeDefinition self, string fullname)
		{
			if (!self.HasNestedTypes)
			{
				return null;
			}
			Collection<TypeDefinition> nestedTypes = self.NestedTypes;
			for (int i = 0; i < nestedTypes.Count; i++)
			{
				TypeDefinition typeDefinition = nestedTypes[i];
				if (typeDefinition.TypeFullName() == fullname)
				{
					return typeDefinition;
				}
			}
			return null;
		}

		public static bool IsPrimitive(this ElementType self)
		{
			switch (self)
			{
			case ElementType.Boolean:
			case ElementType.Char:
			case ElementType.I1:
			case ElementType.U1:
			case ElementType.I2:
			case ElementType.U2:
			case ElementType.I4:
			case ElementType.U4:
			case ElementType.I8:
			case ElementType.U8:
			case ElementType.R4:
			case ElementType.R8:
			case ElementType.I:
			case ElementType.U:
				return true;
			default:
				return false;
			}
		}

		public static string TypeFullName(this TypeReference self)
		{
			if (!string.IsNullOrEmpty(self.Namespace))
			{
				return self.Namespace + "." + self.Name;
			}
			return self.Name;
		}

		public static bool IsTypeOf(this TypeReference self, string @namespace, string name)
		{
			if (self.Name == name)
			{
				return self.Namespace == @namespace;
			}
			return false;
		}

		public static bool IsTypeSpecification(this TypeReference type)
		{
			switch (type.etype)
			{
			case ElementType.Ptr:
			case ElementType.ByRef:
			case ElementType.Var:
			case ElementType.Array:
			case ElementType.GenericInst:
			case ElementType.FnPtr:
			case ElementType.SzArray:
			case ElementType.MVar:
			case ElementType.CModReqD:
			case ElementType.CModOpt:
			case ElementType.Sentinel:
			case ElementType.Pinned:
				return true;
			default:
				return false;
			}
		}

		public static TypeDefinition CheckedResolve(this TypeReference self)
		{
			return self.Resolve() ?? throw new ResolutionException(self);
		}

		public static bool TryGetCoreLibraryReference(this ModuleDefinition module, out AssemblyNameReference reference)
		{
			Collection<AssemblyNameReference> assemblyReferences = module.AssemblyReferences;
			for (int i = 0; i < assemblyReferences.Count; i++)
			{
				reference = assemblyReferences[i];
				if (IsCoreLibrary(reference))
				{
					return true;
				}
			}
			reference = null;
			return false;
		}

		public static bool IsCoreLibrary(this ModuleDefinition module)
		{
			if (module.Assembly == null)
			{
				return false;
			}
			if (!IsCoreLibrary(module.Assembly.Name))
			{
				return false;
			}
			if (module.HasImage && module.Read(module, (ModuleDefinition m, MetadataReader reader) => reader.image.GetTableLength(Table.AssemblyRef) > 0))
			{
				return false;
			}
			return true;
		}

		public static void KnownValueType(this TypeReference type)
		{
			if (!type.IsDefinition)
			{
				type.IsValueType = true;
			}
		}

		private static bool IsCoreLibrary(AssemblyNameReference reference)
		{
			string name = reference.Name;
			switch (name)
			{
			default:
				return name == "netstandard";
			case "mscorlib":
			case "System.Runtime":
			case "System.Private.CoreLib":
				return true;
			}
		}

		public static ImageDebugHeaderEntry GetCodeViewEntry(this ImageDebugHeader header)
		{
			return header.GetEntry(ImageDebugType.CodeView);
		}

		public static ImageDebugHeaderEntry GetDeterministicEntry(this ImageDebugHeader header)
		{
			return header.GetEntry(ImageDebugType.Deterministic);
		}

		public static ImageDebugHeader AddDeterministicEntry(this ImageDebugHeader header)
		{
			ImageDebugDirectory directory = default(ImageDebugDirectory);
			directory.Type = ImageDebugType.Deterministic;
			ImageDebugHeaderEntry imageDebugHeaderEntry = new ImageDebugHeaderEntry(directory, Empty<byte>.Array);
			if (header == null)
			{
				return new ImageDebugHeader(imageDebugHeaderEntry);
			}
			ImageDebugHeaderEntry[] array = new ImageDebugHeaderEntry[header.Entries.Length + 1];
			Array.Copy(header.Entries, array, header.Entries.Length);
			array[^1] = imageDebugHeaderEntry;
			return new ImageDebugHeader(array);
		}

		public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry(this ImageDebugHeader header)
		{
			return header.GetEntry(ImageDebugType.EmbeddedPortablePdb);
		}

		private static ImageDebugHeaderEntry GetEntry(this ImageDebugHeader header, ImageDebugType type)
		{
			if (!header.HasEntries)
			{
				return null;
			}
			for (int i = 0; i < header.Entries.Length; i++)
			{
				ImageDebugHeaderEntry imageDebugHeaderEntry = header.Entries[i];
				if (imageDebugHeaderEntry.Directory.Type == type)
				{
					return imageDebugHeaderEntry;
				}
			}
			return null;
		}

		public static string GetPdbFileName(string assemblyFileName)
		{
			return Path.ChangeExtension(assemblyFileName, ".pdb");
		}

		public static string GetMdbFileName(string assemblyFileName)
		{
			return assemblyFileName + ".mdb";
		}

		public static bool IsPortablePdb(string fileName)
		{
			using FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
			return IsPortablePdb(stream);
		}

		public static bool IsPortablePdb(Stream stream)
		{
			if (stream.Length < 4)
			{
				return false;
			}
			long position = stream.Position;
			try
			{
				return new BinaryReader(stream).ReadUInt32() == 1112167234;
			}
			finally
			{
				stream.Position = position;
			}
		}

		public static uint ReadCompressedUInt32(this byte[] data, ref int position)
		{
			uint result;
			if ((data[position] & 0x80) == 0)
			{
				result = data[position];
				position++;
			}
			else if ((data[position] & 0x40) == 0)
			{
				result = (uint)((data[position] & -129) << 8);
				result |= data[position + 1];
				position += 2;
			}
			else
			{
				result = (uint)((data[position] & -193) << 24);
				result |= (uint)(data[position + 1] << 16);
				result |= (uint)(data[position + 2] << 8);
				result |= data[position + 3];
				position += 4;
			}
			return result;
		}

		public static MetadataToken GetMetadataToken(this CodedIndex self, uint data)
		{
			uint rid;
			TokenType type;
			switch (self)
			{
			case CodedIndex.TypeDefOrRef:
				rid = data >> 2;
				switch (data & 3)
				{
				case 0u:
					break;
				case 1u:
					goto IL_006d;
				case 2u:
					goto IL_0078;
				default:
					goto end_IL_0001;
				}
				type = TokenType.TypeDef;
				goto IL_05b3;
			case CodedIndex.HasConstant:
				rid = data >> 2;
				switch (data & 3)
				{
				case 0u:
					break;
				case 1u:
					goto IL_00ad;
				case 2u:
					goto IL_00b8;
				default:
					goto end_IL_0001;
				}
				type = TokenType.Field;
				goto IL_05b3;
			case CodedIndex.HasCustomAttribute:
				rid = data >> 5;
				switch (data & 0x1F)
				{
				case 0u:
					break;
				case 1u:
					goto IL_013a;
				case 2u:
					goto IL_0145;
				case 3u:
					goto IL_0150;
				case 4u:
					goto IL_015b;
				case 5u:
					goto IL_0166;
				case 6u:
					goto IL_0171;
				case 7u:
					goto IL_017c;
				case 8u:
					goto IL_0183;
				case 9u:
					goto IL_018e;
				case 10u:
					goto IL_0199;
				case 11u:
					goto IL_01a4;
				case 12u:
					goto IL_01af;
				case 13u:
					goto IL_01ba;
				case 14u:
					goto IL_01c5;
				case 15u:
					goto IL_01d0;
				case 16u:
					goto IL_01db;
				case 17u:
					goto IL_01e6;
				case 18u:
					goto IL_01f1;
				case 19u:
					goto IL_01fc;
				case 20u:
					goto IL_0207;
				case 21u:
					goto IL_0212;
				default:
					goto end_IL_0001;
				}
				type = TokenType.Method;
				goto IL_05b3;
			case CodedIndex.HasFieldMarshal:
			{
				rid = data >> 1;
				uint num = data & 1u;
				if (num != 0)
				{
					if (num != 1)
					{
						break;
					}
					type = TokenType.Param;
				}
				else
				{
					type = TokenType.Field;
				}
				goto IL_05b3;
			}
			case CodedIndex.HasDeclSecurity:
				rid = data >> 2;
				switch (data & 3)
				{
				case 0u:
					break;
				case 1u:
					goto IL_0271;
				case 2u:
					goto IL_027c;
				default:
					goto end_IL_0001;
				}
				type = TokenType.TypeDef;
				goto IL_05b3;
			case CodedIndex.MemberRefParent:
				rid = data >> 3;
				switch (data & 7)
				{
				case 0u:
					break;
				case 1u:
					goto IL_02b9;
				case 2u:
					goto IL_02c4;
				case 3u:
					goto IL_02cf;
				case 4u:
					goto IL_02da;
				default:
					goto end_IL_0001;
				}
				type = TokenType.TypeDef;
				goto IL_05b3;
			case CodedIndex.HasSemantics:
			{
				rid = data >> 1;
				uint num = data & 1u;
				if (num != 0)
				{
					if (num != 1)
					{
						break;
					}
					type = TokenType.Property;
				}
				else
				{
					type = TokenType.Event;
				}
				goto IL_05b3;
			}
			case CodedIndex.MethodDefOrRef:
			{
				rid = data >> 1;
				uint num = data & 1u;
				if (num != 0)
				{
					if (num != 1)
					{
						break;
					}
					type = TokenType.MemberRef;
				}
				else
				{
					type = TokenType.Method;
				}
				goto IL_05b3;
			}
			case CodedIndex.MemberForwarded:
			{
				rid = data >> 1;
				uint num = data & 1u;
				if (num != 0)
				{
					if (num != 1)
					{
						break;
					}
					type = TokenType.Method;
				}
				else
				{
					type = TokenType.Field;
				}
				goto IL_05b3;
			}
			case CodedIndex.Implementation:
				rid = data >> 2;
				switch (data & 3)
				{
				case 0u:
					break;
				case 1u:
					goto IL_038d;
				case 2u:
					goto IL_0398;
				default:
					goto end_IL_0001;
				}
				type = TokenType.File;
				goto IL_05b3;
			case CodedIndex.CustomAttributeType:
			{
				rid = data >> 3;
				uint num = data & 7u;
				if (num != 2)
				{
					if (num != 3)
					{
						break;
					}
					type = TokenType.MemberRef;
				}
				else
				{
					type = TokenType.Method;
				}
				goto IL_05b3;
			}
			case CodedIndex.ResolutionScope:
				rid = data >> 2;
				switch (data & 3)
				{
				case 0u:
					break;
				case 1u:
					goto IL_03f8;
				case 2u:
					goto IL_0403;
				case 3u:
					goto IL_040e;
				default:
					goto end_IL_0001;
				}
				type = TokenType.Module;
				goto IL_05b3;
			case CodedIndex.TypeOrMethodDef:
			{
				rid = data >> 1;
				uint num = data & 1u;
				if (num != 0)
				{
					if (num != 1)
					{
						break;
					}
					type = TokenType.Method;
				}
				else
				{
					type = TokenType.TypeDef;
				}
				goto IL_05b3;
			}
			case CodedIndex.HasCustomDebugInformation:
				{
					rid = data >> 5;
					switch (data & 0x1F)
					{
					case 0u:
						break;
					case 1u:
						goto IL_04ce;
					case 2u:
						goto IL_04d9;
					case 3u:
						goto IL_04e4;
					case 4u:
						goto IL_04ef;
					case 5u:
						goto IL_04fa;
					case 6u:
						goto IL_0505;
					case 7u:
						goto IL_0510;
					case 8u:
						goto IL_0517;
					case 9u:
						goto IL_0522;
					case 10u:
						goto IL_052d;
					case 11u:
						goto IL_0535;
					case 12u:
						goto IL_053d;
					case 13u:
						goto IL_0545;
					case 14u:
						goto IL_054d;
					case 15u:
						goto IL_0555;
					case 16u:
						goto IL_055d;
					case 17u:
						goto IL_0565;
					case 18u:
						goto IL_056d;
					case 19u:
						goto IL_0575;
					case 20u:
						goto IL_057d;
					case 21u:
						goto IL_0585;
					case 22u:
						goto IL_058d;
					case 23u:
						goto IL_0595;
					case 24u:
						goto IL_059d;
					case 25u:
						goto IL_05a5;
					case 26u:
						goto IL_05ad;
					default:
						goto end_IL_0001;
					}
					type = TokenType.Method;
					goto IL_05b3;
				}
				IL_05ad:
				type = TokenType.ImportScope;
				goto IL_05b3;
				IL_05a5:
				type = TokenType.LocalConstant;
				goto IL_05b3;
				IL_059d:
				type = TokenType.LocalVariable;
				goto IL_05b3;
				IL_0595:
				type = TokenType.LocalScope;
				goto IL_05b3;
				IL_058d:
				type = TokenType.Document;
				goto IL_05b3;
				IL_0585:
				type = TokenType.MethodSpec;
				goto IL_05b3;
				IL_057d:
				type = TokenType.GenericParamConstraint;
				goto IL_05b3;
				IL_0575:
				type = TokenType.GenericParam;
				goto IL_05b3;
				IL_056d:
				type = TokenType.ManifestResource;
				goto IL_05b3;
				IL_0565:
				type = TokenType.ExportedType;
				goto IL_05b3;
				IL_055d:
				type = TokenType.File;
				goto IL_05b3;
				IL_0555:
				type = TokenType.AssemblyRef;
				goto IL_05b3;
				IL_054d:
				type = TokenType.Assembly;
				goto IL_05b3;
				IL_0545:
				type = TokenType.TypeSpec;
				goto IL_05b3;
				IL_053d:
				type = TokenType.ModuleRef;
				goto IL_05b3;
				IL_0535:
				type = TokenType.Signature;
				goto IL_05b3;
				IL_052d:
				type = TokenType.Event;
				goto IL_05b3;
				IL_0522:
				type = TokenType.Property;
				goto IL_05b3;
				IL_0517:
				type = TokenType.Permission;
				goto IL_05b3;
				IL_0510:
				type = TokenType.Module;
				goto IL_05b3;
				IL_0505:
				type = TokenType.MemberRef;
				goto IL_05b3;
				IL_04fa:
				type = TokenType.InterfaceImpl;
				goto IL_05b3;
				IL_04ef:
				type = TokenType.Param;
				goto IL_05b3;
				IL_04e4:
				type = TokenType.TypeDef;
				goto IL_05b3;
				IL_04d9:
				type = TokenType.TypeRef;
				goto IL_05b3;
				IL_04ce:
				type = TokenType.Field;
				goto IL_05b3;
				IL_01db:
				type = TokenType.File;
				goto IL_05b3;
				IL_01d0:
				type = TokenType.AssemblyRef;
				goto IL_05b3;
				IL_01ba:
				type = TokenType.TypeSpec;
				goto IL_05b3;
				IL_01c5:
				type = TokenType.Assembly;
				goto IL_05b3;
				IL_040e:
				type = TokenType.TypeRef;
				goto IL_05b3;
				IL_0403:
				type = TokenType.AssemblyRef;
				goto IL_05b3;
				IL_03f8:
				type = TokenType.ModuleRef;
				goto IL_05b3;
				IL_01af:
				type = TokenType.ModuleRef;
				goto IL_05b3;
				IL_01a4:
				type = TokenType.Signature;
				goto IL_05b3;
				IL_018e:
				type = TokenType.Property;
				goto IL_05b3;
				IL_0199:
				type = TokenType.Event;
				goto IL_05b3;
				IL_0398:
				type = TokenType.ExportedType;
				goto IL_05b3;
				IL_038d:
				type = TokenType.AssemblyRef;
				goto IL_05b3;
				IL_0183:
				type = TokenType.Permission;
				goto IL_05b3;
				IL_017c:
				type = TokenType.Module;
				goto IL_05b3;
				IL_0166:
				type = TokenType.InterfaceImpl;
				goto IL_05b3;
				IL_0171:
				type = TokenType.MemberRef;
				goto IL_05b3;
				IL_015b:
				type = TokenType.Param;
				goto IL_05b3;
				IL_0145:
				type = TokenType.TypeRef;
				goto IL_05b3;
				IL_0150:
				type = TokenType.TypeDef;
				goto IL_05b3;
				IL_013a:
				type = TokenType.Field;
				goto IL_05b3;
				IL_006d:
				type = TokenType.TypeRef;
				goto IL_05b3;
				IL_02da:
				type = TokenType.TypeSpec;
				goto IL_05b3;
				IL_02cf:
				type = TokenType.Method;
				goto IL_05b3;
				IL_02c4:
				type = TokenType.ModuleRef;
				goto IL_05b3;
				IL_02b9:
				type = TokenType.TypeRef;
				goto IL_05b3;
				IL_00b8:
				type = TokenType.Property;
				goto IL_05b3;
				IL_027c:
				type = TokenType.Assembly;
				goto IL_05b3;
				IL_0271:
				type = TokenType.Method;
				goto IL_05b3;
				IL_00ad:
				type = TokenType.Param;
				goto IL_05b3;
				IL_05b3:
				return new MetadataToken(type, rid);
				IL_0078:
				type = TokenType.TypeSpec;
				goto IL_05b3;
				IL_0212:
				type = TokenType.MethodSpec;
				goto IL_05b3;
				IL_0207:
				type = TokenType.GenericParamConstraint;
				goto IL_05b3;
				IL_01fc:
				type = TokenType.GenericParam;
				goto IL_05b3;
				IL_01f1:
				type = TokenType.ManifestResource;
				goto IL_05b3;
				IL_01e6:
				type = TokenType.ExportedType;
				goto IL_05b3;
				end_IL_0001:
				break;
			}
			return MetadataToken.Zero;
		}

		public static uint CompressMetadataToken(this CodedIndex self, MetadataToken token)
		{
			uint result = 0u;
			if (token.RID == 0)
			{
				return result;
			}
			switch (self)
			{
			case CodedIndex.TypeDefOrRef:
				result = token.RID << 2;
				switch (token.TokenType)
				{
				case TokenType.TypeDef:
					return result | 0u;
				case TokenType.TypeRef:
					return result | 1u;
				case TokenType.TypeSpec:
					return result | 2u;
				}
				break;
			case CodedIndex.HasConstant:
				result = token.RID << 2;
				switch (token.TokenType)
				{
				case TokenType.Field:
					return result | 0u;
				case TokenType.Param:
					return result | 1u;
				case TokenType.Property:
					return result | 2u;
				}
				break;
			case CodedIndex.HasCustomAttribute:
				result = token.RID << 5;
				switch (token.TokenType)
				{
				case TokenType.Method:
					return result | 0u;
				case TokenType.Field:
					return result | 1u;
				case TokenType.TypeRef:
					return result | 2u;
				case TokenType.TypeDef:
					return result | 3u;
				case TokenType.Param:
					return result | 4u;
				case TokenType.InterfaceImpl:
					return result | 5u;
				case TokenType.MemberRef:
					return result | 6u;
				case TokenType.Module:
					return result | 7u;
				case TokenType.Permission:
					return result | 8u;
				case TokenType.Property:
					return result | 9u;
				case TokenType.Event:
					return result | 0xAu;
				case TokenType.Signature:
					return result | 0xBu;
				case TokenType.ModuleRef:
					return result | 0xCu;
				case TokenType.TypeSpec:
					return result | 0xDu;
				case TokenType.Assembly:
					return result | 0xEu;
				case TokenType.AssemblyRef:
					return result | 0xFu;
				case TokenType.File:
					return result | 0x10u;
				case TokenType.ExportedType:
					return result | 0x11u;
				case TokenType.ManifestResource:
					return result | 0x12u;
				case TokenType.GenericParam:
					return result | 0x13u;
				case TokenType.GenericParamConstraint:
					return result | 0x14u;
				case TokenType.MethodSpec:
					return result | 0x15u;
				}
				break;
			case CodedIndex.HasFieldMarshal:
				result = token.RID << 1;
				switch (token.TokenType)
				{
				case TokenType.Field:
					return result | 0u;
				case TokenType.Param:
					return result | 1u;
				}
				break;
			case CodedIndex.HasDeclSecurity:
				result = token.RID << 2;
				switch (token.TokenType)
				{
				case TokenType.TypeDef:
					return result | 0u;
				case TokenType.Method:
					return result | 1u;
				case TokenType.Assembly:
					return result | 2u;
				}
				break;
			case CodedIndex.MemberRefParent:
				result = token.RID << 3;
				switch (token.TokenType)
				{
				case TokenType.TypeDef:
					return result | 0u;
				case TokenType.TypeRef:
					return result | 1u;
				case TokenType.ModuleRef:
					return result | 2u;
				case TokenType.Method:
					return result | 3u;
				case TokenType.TypeSpec:
					return result | 4u;
				}
				break;
			case CodedIndex.HasSemantics:
				result = token.RID << 1;
				switch (token.TokenType)
				{
				case TokenType.Event:
					return result | 0u;
				case TokenType.Property:
					return result | 1u;
				}
				break;
			case CodedIndex.MethodDefOrRef:
				result = token.RID << 1;
				switch (token.TokenType)
				{
				case TokenType.Method:
					return result | 0u;
				case TokenType.MemberRef:
					return result | 1u;
				}
				break;
			case CodedIndex.MemberForwarded:
				result = token.RID << 1;
				switch (token.TokenType)
				{
				case TokenType.Field:
					return result | 0u;
				case TokenType.Method:
					return result | 1u;
				}
				break;
			case CodedIndex.Implementation:
				result = token.RID << 2;
				switch (token.TokenType)
				{
				case TokenType.File:
					return result | 0u;
				case TokenType.AssemblyRef:
					return result | 1u;
				case TokenType.ExportedType:
					return result | 2u;
				}
				break;
			case CodedIndex.CustomAttributeType:
				result = token.RID << 3;
				switch (token.TokenType)
				{
				case TokenType.Method:
					return result | 2u;
				case TokenType.MemberRef:
					return result | 3u;
				}
				break;
			case CodedIndex.ResolutionScope:
				result = token.RID << 2;
				switch (token.TokenType)
				{
				case TokenType.Module:
					return result | 0u;
				case TokenType.ModuleRef:
					return result | 1u;
				case TokenType.AssemblyRef:
					return result | 2u;
				case TokenType.TypeRef:
					return result | 3u;
				}
				break;
			case CodedIndex.TypeOrMethodDef:
				result = token.RID << 1;
				switch (token.TokenType)
				{
				case TokenType.TypeDef:
					return result | 0u;
				case TokenType.Method:
					return result | 1u;
				}
				break;
			case CodedIndex.HasCustomDebugInformation:
				result = token.RID << 5;
				switch (token.TokenType)
				{
				case TokenType.Method:
					return result | 0u;
				case TokenType.Field:
					return result | 1u;
				case TokenType.TypeRef:
					return result | 2u;
				case TokenType.TypeDef:
					return result | 3u;
				case TokenType.Param:
					return result | 4u;
				case TokenType.InterfaceImpl:
					return result | 5u;
				case TokenType.MemberRef:
					return result | 6u;
				case TokenType.Module:
					return result | 7u;
				case TokenType.Permission:
					return result | 8u;
				case TokenType.Property:
					return result | 9u;
				case TokenType.Event:
					return result | 0xAu;
				case TokenType.Signature:
					return result | 0xBu;
				case TokenType.ModuleRef:
					return result | 0xCu;
				case TokenType.TypeSpec:
					return result | 0xDu;
				case TokenType.Assembly:
					return result | 0xEu;
				case TokenType.AssemblyRef:
					return result | 0xFu;
				case TokenType.File:
					return result | 0x10u;
				case TokenType.ExportedType:
					return result | 0x11u;
				case TokenType.ManifestResource:
					return result | 0x12u;
				case TokenType.GenericParam:
					return result | 0x13u;
				case TokenType.GenericParamConstraint:
					return result | 0x14u;
				case TokenType.MethodSpec:
					return result | 0x15u;
				case TokenType.Document:
					return result | 0x16u;
				case TokenType.LocalScope:
					return result | 0x17u;
				case TokenType.LocalVariable:
					return result | 0x18u;
				case TokenType.LocalConstant:
					return result | 0x19u;
				case TokenType.ImportScope:
					return result | 0x1Au;
				}
				break;
			}
			throw new ArgumentException();
		}

		public static int GetSize(this CodedIndex self, Func<Table, int> counter)
		{
			int num;
			Table[] array;
			switch (self)
			{
			case CodedIndex.TypeDefOrRef:
				num = 2;
				array = new Table[3]
				{
					Table.TypeDef,
					Table.TypeRef,
					Table.TypeSpec
				};
				break;
			case CodedIndex.HasConstant:
				num = 2;
				array = new Table[3]
				{
					Table.Field,
					Table.Param,
					Table.Property
				};
				break;
			case CodedIndex.HasCustomAttribute:
				num = 5;
				array = new Table[22]
				{
					Table.Method,
					Table.Field,
					Table.TypeRef,
					Table.TypeDef,
					Table.Param,
					Table.InterfaceImpl,
					Table.MemberRef,
					Table.Module,
					Table.DeclSecurity,
					Table.Property,
					Table.Event,
					Table.StandAloneSig,
					Table.ModuleRef,
					Table.TypeSpec,
					Table.Assembly,
					Table.AssemblyRef,
					Table.File,
					Table.ExportedType,
					Table.ManifestResource,
					Table.GenericParam,
					Table.GenericParamConstraint,
					Table.MethodSpec
				};
				break;
			case CodedIndex.HasFieldMarshal:
				num = 1;
				array = new Table[2]
				{
					Table.Field,
					Table.Param
				};
				break;
			case CodedIndex.HasDeclSecurity:
				num = 2;
				array = new Table[3]
				{
					Table.TypeDef,
					Table.Method,
					Table.Assembly
				};
				break;
			case CodedIndex.MemberRefParent:
				num = 3;
				array = new Table[5]
				{
					Table.TypeDef,
					Table.TypeRef,
					Table.ModuleRef,
					Table.Method,
					Table.TypeSpec
				};
				break;
			case CodedIndex.HasSemantics:
				num = 1;
				array = new Table[2]
				{
					Table.Event,
					Table.Property
				};
				break;
			case CodedIndex.MethodDefOrRef:
				num = 1;
				array = new Table[2]
				{
					Table.Method,
					Table.MemberRef
				};
				break;
			case CodedIndex.MemberForwarded:
				num = 1;
				array = new Table[2]
				{
					Table.Field,
					Table.Method
				};
				break;
			case CodedIndex.Implementation:
				num = 2;
				array = new Table[3]
				{
					Table.File,
					Table.AssemblyRef,
					Table.ExportedType
				};
				break;
			case CodedIndex.CustomAttributeType:
				num = 3;
				array = new Table[2]
				{
					Table.Method,
					Table.MemberRef
				};
				break;
			case CodedIndex.ResolutionScope:
				num = 2;
				array = new Table[4]
				{
					Table.Module,
					Table.ModuleRef,
					Table.AssemblyRef,
					Table.TypeRef
				};
				break;
			case CodedIndex.TypeOrMethodDef:
				num = 1;
				array = new Table[2]
				{
					Table.TypeDef,
					Table.Method
				};
				break;
			case CodedIndex.HasCustomDebugInformation:
				num = 5;
				array = new Table[27]
				{
					Table.Method,
					Table.Field,
					Table.TypeRef,
					Table.TypeDef,
					Table.Param,
					Table.InterfaceImpl,
					Table.MemberRef,
					Table.Module,
					Table.DeclSecurity,
					Table.Property,
					Table.Event,
					Table.StandAloneSig,
					Table.ModuleRef,
					Table.TypeSpec,
					Table.Assembly,
					Table.AssemblyRef,
					Table.File,
					Table.ExportedType,
					Table.ManifestResource,
					Table.GenericParam,
					Table.GenericParamConstraint,
					Table.MethodSpec,
					Table.Document,
					Table.LocalScope,
					Table.LocalVariable,
					Table.LocalConstant,
					Table.ImportScope
				};
				break;
			default:
				throw new ArgumentException();
			}
			int num2 = 0;
			for (int i = 0; i < array.Length; i++)
			{
				num2 = Math.Max(counter(array[i]), num2);
			}
			if (num2 >= 1 << 16 - num)
			{
				return 4;
			}
			return 2;
		}

		public static RSA CreateRSA(this StrongNameKeyPair key_pair)
		{
			if (!TryGetKeyContainer(key_pair, out var key, out var key_container))
			{
				return CryptoConvert.FromCapiKeyBlob(key);
			}
			return new RSACryptoServiceProvider(new CspParameters
			{
				Flags = CspProviderFlags.UseMachineKeyStore,
				KeyContainerName = key_container,
				KeyNumber = 2
			});
		}

		private static bool TryGetKeyContainer(ISerializable key_pair, out byte[] key, out string key_container)
		{
			SerializationInfo serializationInfo = new SerializationInfo(typeof(StrongNameKeyPair), new FormatterConverter());
			key_pair.GetObjectData(serializationInfo, default(StreamingContext));
			key = (byte[])serializationInfo.GetValue("_keyPairArray", typeof(byte[]));
			key_container = serializationInfo.GetString("_keyPairContainer");
			return key_container != null;
		}
	}
	public struct ArrayDimension
	{
		private int? lower_bound;

		private int? upper_bound;

		public int? LowerBound
		{
			get
			{
				return lower_bound;
			}
			set
			{
				lower_bound = value;
			}
		}

		public int? UpperBound
		{
			get
			{
				return upper_bound;
			}
			set
			{
				upper_bound = value;
			}
		}

		public bool IsSized
		{
			get
			{
				if (!lower_bound.HasValue)
				{
					return upper_bound.HasValue;
				}
				return true;
			}
		}

		public ArrayDimension(int? lowerBound, int? upperBound)
		{
			lower_bound = lowerBound;
			upper_bound = upperBound;
		}

		public override string ToString()
		{
			if (IsSized)
			{
				return lower_bound + "..." + upper_bound;
			}
			return string.Empty;
		}
	}
	public sealed class ArrayType : TypeSpecification
	{
		private Collection<ArrayDimension> dimensions;

		public Collection<ArrayDimension> Dimensions
		{
			get
			{
				if (dimensions != null)
				{
					return dimensions;
				}
				dimensions = new Collection<ArrayDimension>();
				dimensions.Add(default(ArrayDimension));
				return dimensions;
			}
		}

		public int Rank
		{
			get
			{
				if (dimensions != null)
				{
					return dimensions.Count;
				}
				return 1;
			}
		}

		public bool IsVector
		{
			get
			{
				if (dimensions == null)
				{
					return true;
				}
				if (dimensions.Count > 1)
				{
					return false;
				}
				return !dimensions[0].IsSized;
			}
		}

		public override bool IsValueType
		{
			get
			{
				return false;
			}
			set
			{
				throw new InvalidOperationException();
			}
		}

		public override string Name => base.Name + Suffix;

		public override string FullName => base.FullName + Suffix;

		private string Suffix
		{
			get
			{
				if (IsVector)
				{
					return "[]";
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[");
				for (int i = 0; i < dimensions.Count; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(",");
					}
					stringBuilder.Append(dimensions[i].ToString());
				}
				stringBuilder.Append("]");
				return stringBuilder.ToString();
			}
		}

		public override bool IsArray => true;

		public ArrayType(TypeReference type)
			: base(type)
		{
			Mixin.CheckType(type);
			etype = Mono.Cecil.Metadata.ElementType.Array;
		}

		public ArrayType(TypeReference type, int rank)
			: this(type)
		{
			Mixin.CheckType(type);
			if (rank != 1)
			{
				dimensions = new Collection<ArrayDimension>(rank);
				for (int i = 0; i < rank; i++)
				{
					dimensions.Add(default(ArrayDimension));
				}
				etype = Mono.Cecil.Metadata.ElementType.Array;
			}
		}
	}
	public sealed class AssemblyDefinition : ICustomAttributeProvider, IMetadataTokenProvider, ISecurityDeclarationProvider, IDisposable
	{
		private AssemblyNameDefinition name;

		internal ModuleDefinition main_module;

		private Collection<ModuleDefinition> modules;

		private Collection<CustomAttribute> custom_attributes;

		private Collection<SecurityDeclaration> security_declarations;

		public AssemblyNameDefinition Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public string FullName
		{
			get
			{
				if (name == null)
				{
					return string.Empty;
				}
				return name.FullName;
			}
		}

		public MetadataToken MetadataToken
		{
			get
			{
				return new MetadataToken(TokenType.Assembly, 1);
			}
			set
			{
			}
		}

		public Collection<ModuleDefinition> Modules
		{
			get
			{
				if (modules != null)
				{
					return modules;
				}
				if (main_module.HasImage)
				{
					return main_module.Read(ref modules, this, (AssemblyDefinition _, MetadataReader reader) => reader.ReadModules());
				}
				return modules = new Collection<ModuleDefinition>(1) { main_module };
			}
		}

		public ModuleDefinition MainModule => main_module;

		public MethodDefinition EntryPoint
		{
			get
			{
				return main_module.EntryPoint;
			}
			set
			{
				main_module.EntryPoint = value;
			}
		}

		public bool HasCustomAttributes
		{
			get
			{
				if (custom_attributes != null)
				{
					return custom_attributes.Count > 0;
				}
				return this.GetHasCustomAttributes(main_module);
			}
		}

		public Collection<CustomAttribute> CustomAttributes => custom_attributes ?? this.GetCustomAttributes(ref custom_attributes, main_module);

		public bool HasSecurityDeclarations
		{
			get
			{
				if (security_declarations != null)
				{
					return security_declarations.Count > 0;
				}
				return this.GetHasSecurityDeclarations(main_module);
			}
		}

		public Collection<SecurityDeclaration> SecurityDeclarations => security_declarations ?? this.GetSecurityDeclarations(ref security_declarations, main_module);

		internal AssemblyDefinition()
		{
		}

		public void Dispose()
		{
			if (modules == null)
			{
				main_module.Dispose();
				return;
			}
			Collection<ModuleDefinition> collection = Modules;
			for (int i = 0; i < collection.Count; i++)
			{
				collection[i].Dispose();
			}
		}

		public static AssemblyDefinition CreateAssembly(AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind)
		{
			return CreateAssembly(assemblyName, moduleName, new ModuleParameters
			{
				Kind = kind
			});
		}

		public static AssemblyDefinition CreateAssembly(AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters)
		{
			if (assemblyName == null)
			{
				throw new ArgumentNullException("assemblyName");
			}
			if (moduleName == null)
			{
				throw new ArgumentNullException("moduleName");
			}
			Mixin.CheckParameters(parameters);
			if (parameters.Kind == ModuleKind.NetModule)
			{
				throw new ArgumentException("kind");
			}
			AssemblyDefinition assembly = ModuleDefinition.CreateModule(moduleName, parameters).Assembly;
			assembly.Name = assemblyName;
			return assembly;
		}

		public static AssemblyDefinition ReadAssembly(string fileName)
		{
			return ReadAssembly(ModuleDefinition.ReadModule(fileName));
		}

		public static AssemblyDefinition ReadAssembly(string fileName, ReaderParameters parameters)
		{
			return ReadAssembly(ModuleDefinition.ReadModule(fileName, parameters));
		}

		public static AssemblyDefinition ReadAssembly(Stream stream)
		{
			return ReadAssembly(ModuleDefinition.ReadModule(stream));
		}

		public static AssemblyDefinition ReadAssembly(Stream stream, ReaderParameters parameters)
		{
			return ReadAssembly(ModuleDefinition.ReadModule(stream, parameters));
		}

		private static AssemblyDefinition ReadAssembly(ModuleDefinition module)
		{
			return module.Assembly ?? throw new ArgumentException();
		}

		public void Write(string fileName)
		{
			Write(fileName, new WriterParameters());
		}

		public void Write(string fileName, WriterParameters parameters)
		{
			main_module.Write(fileName, parameters);
		}

		public void Write()
		{
			main_module.Write();
		}

		public void Write(WriterParameters parameters)
		{
			main_module.Write(parameters);
		}

		public void Write(Stream stream)
		{
			Write(stream, new WriterParameters());
		}

		public void Write(Stream stream, WriterParameters parameters)
		{
			main_module.Write(stream, parameters);
		}

		public override string ToString()
		{
			return FullName;
		}
	}
	[Flags]
	public enum AssemblyAttributes : uint
	{
		PublicKey = 1u,
		SideBySideCompatible = 0u,
		Retargetable = 0x100u,
		WindowsRuntime = 0x200u,
		DisableJITCompileOptimizer = 0x4000u,
		EnableJITCompileTracking = 0x8000u
	}
	public enum AssemblyHashAlgorithm : uint
	{
		None = 0u,
		Reserved = 32771u,
		SHA1 = 32772u
	}
	public sealed class AssemblyLinkedResource : Resource
	{
		private AssemblyNameReference reference;

		public AssemblyNameReference Assembly
		{
			get
			{
				return reference;
			}
			set
			{
				reference = value;
			}
		}

		public override ResourceType ResourceType => ResourceType.AssemblyLinked;

		public AssemblyLinkedResource(string name, ManifestResourceAttributes flags)
			: base(name, flags)
		{
		}

		public AssemblyLinkedResource(string name, ManifestResourceAttributes flags, AssemblyNameReference reference)
			: base(name, flags)
		{
			this.reference = reference;
		}
	}
	public sealed class AssemblyNameDefinition : AssemblyNameReference
	{
		public override byte[] Hash => Empty<byte>.Array;

		internal AssemblyNameDefinition()
		{
			token = new MetadataToken(TokenType.Assembly, 1);
		}

		public AssemblyNameDefinition(string name, Version version)
			: base(name, version)
		{
			token = new MetadataToken(TokenType.Assembly, 1);
		}
	}
	public class AssemblyNameReference : IMetadataScope, IMetadataTokenProvider
	{
		private string name;

		private string culture;

		private Version version;

		private uint attributes;

		private byte[] public_key;

		private byte[] public_key_token;

		private AssemblyHashAlgorithm hash_algorithm;

		private byte[] hash;

		internal MetadataToken token;

		private string full_name;

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
				full_name = null;
			}
		}

		public string Culture
		{
			get
			{
				return culture;
			}
			set
			{
				culture = value;
				full_name = null;
			}
		}

		public Version Version
		{
			get
			{
				return version;
			}
			set
			{
				version = Mixin.CheckVersion(value);
				full_name = null;
			}
		}

		public AssemblyAttributes Attributes
		{
			get
			{
				return (AssemblyAttributes)attributes;
			}
			set
			{
				attributes = (uint)value;
			}
		}

		public bool HasPublicKey
		{
			get
			{
				return attributes.GetAttributes(1u);
			}
			set
			{
				attributes = attributes.SetAttributes(1u, value);
			}
		}

		public bool IsSideBySideCompatible
		{
			get
			{
				return attributes.GetAttributes(0u);
			}
			set
			{
				attributes = attributes.SetAttributes(0u, value);
			}
		}

		public bool IsRetargetable
		{
			get
			{
				return attributes.GetAttributes(256u);
			}
			set
			{
				attributes = attributes.SetAttributes(256u, value);
			}
		}

		public bool IsWindowsRuntime
		{
			get
			{
				return attributes.GetAttributes(512u);
			}
			set
			{
				attributes = attributes.SetAttributes(512u, value);
			}
		}

		public byte[] PublicKey
		{
			get
			{
				return public_key ?? Empty<byte>.Array;
			}
			set
			{
				public_key = value;
				HasPublicKey = !public_key.IsNullOrEmpty();
				public_key_token = Empty<byte>.Array;
				full_name = null;
			}
		}

		public byte[] PublicKeyToken
		{
			get
			{
				if (public_key_token.IsNullOrEmpty() && !public_key.IsNullOrEmpty())
				{
					byte[] array = HashPublicKey();
					byte[] array2 = new byte[8];
					Array.Copy(array, array.Length - 8, array2, 0, 8);
					Array.Reverse((Array)array2, 0, 8);
					public_key_token = array2;
				}
				return public_key_token ?? Empty<byte>.Array;
			}
			set
			{
				public_key_token = value;
				full_name = null;
			}
		}

		public virtual MetadataScopeType MetadataScopeType => MetadataScopeType.AssemblyNameReference;

		public string FullName
		{
			get
			{
				if (full_name != null)
				{
					return full_name;
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append(name);
				stringBuilder.Append(", ");
				stringBuilder.Append("Version=");
				stringBuilder.Append(version.ToString(4));
				stringBuilder.Append(", ");
				stringBuilder.Append("Culture=");
				stringBuilder.Append(string.IsNullOrEmpty(culture) ? "neutral" : culture);
				stringBuilder.Append(", ");
				stringBuilder.Append("PublicKeyToken=");
				byte[] publicKeyToken = PublicKeyToken;
				if (!publicKeyToken.IsNullOrEmpty() && publicKeyToken.Length != 0)
				{
					for (int i = 0; i < publicKeyToken.Length; i++)
					{
						stringBuilder.Append(publicKeyToken[i].ToString("x2"));
					}
				}
				else
				{
					stringBuilder.Append("null");
				}
				if (IsRetargetable)
				{
					stringBuilder.Append(", ");
					stringBuilder.Append("Retargetable=Yes");
				}
				return full_name = stringBuilder.ToString();
			}
		}

		public AssemblyHashAlgorithm HashAlgorithm
		{
			get
			{
				return hash_algorithm;
			}
			set
			{
				hash_algorithm = value;
			}
		}

		public virtual byte[] Hash
		{
			get
			{
				return hash;
			}
			set
			{
				hash = value;
			}
		}

		public MetadataToken MetadataToken
		{
			get
			{
				return token;
			}
			set
			{
				token = value;
			}
		}

		private byte[] HashPublicKey()
		{
			AssemblyHashAlgorithm assemblyHashAlgorithm = hash_algorithm;
			HashAlgorithm hashAlgorithm = ((assemblyHashAlgorithm != AssemblyHashAlgorithm.Reserved) ? ((HashAlgorithm)SHA1.Create()) : ((HashAlgorithm)MD5.Create()));
			using (hashAlgorithm)
			{
				return hashAlgorithm.ComputeHash(public_key);
			}
		}

		public static AssemblyNameReference Parse(string fullName)
		{
			if (fullName == null)
			{
				throw new ArgumentNullException("fullName");
			}
			if (fullName.Length == 0)
			{
				throw new ArgumentException("Name can not be empty");
			}
			AssemblyNameReference assemblyNameReference = new AssemblyNameReference();
			string[] array = fullName.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (i == 0)
				{
					assemblyNameReference.Name = text;
					continue;
				}
				string[] array2 = text.Split(new char[1] { '=' });
				if (array2.Length != 2)
				{
					throw new ArgumentException("Malformed name");
				}
				switch (array2[0].ToLowerInvariant())
				{
				case "version":
					assemblyNameReference.Version = new Version(array2[1]);
					break;
				case "culture":
					assemblyNameReference.Culture = ((array2[1] == "neutral") ? "" : array2[1]);
					break;
				case "publickeytoken":
				{
					string text2 = array2[1];
					if (!(text2 == "null"))
					{
						assemblyNameReference.PublicKeyToken = new byte[text2.Length / 2];
						for (int j = 0; j < assemblyNameReference.PublicKeyToken.Length; j++)
						{
							assemblyNameReference.PublicKeyToken[j] = byte.Parse(text2.Substring(j * 2, 2), NumberStyles.HexNumber);
						}
					}
					break;
				}
				}
			}
			return assemblyNameReference;
		}

		internal AssemblyNameReference()
		{
			version = Mixin.ZeroVersion;
			token = new MetadataToken(TokenType.AssemblyRef);
		}

		public AssemblyNameReference(string name, Version version)
		{
			Mixin.CheckName(name);
			this.name = name;
			this.version = Mixin.CheckVersion(version);
			hash_algorithm = AssemblyHashAlgorithm.None;
			token = new MetadataToken(TokenType.AssemblyRef);
		}

		public override string ToString()
		{
			return FullName;
		}
	}
	internal abstract class ModuleReader
	{
		protected readonly ModuleDefinition module;

		protected ModuleReader(Image image, ReadingMode mode)
		{
			module = new ModuleDefinition(image);
			module.ReadingMode = mode;
		}

		protected abstract void ReadModule();

		public abstract void ReadSymbols(ModuleDefinition module);

		protected void ReadModuleManifest(MetadataReader reader)
		{
			reader.Populate(module);
			ReadAssembly(reader);
		}

		private void ReadAssembly(MetadataReader reader)
		{
			AssemblyNameDefinition assemblyNameDefinition = reader.ReadAssemblyNameDefinition();
			if (assemblyNameDefinition == null)
			{
				module.kind = ModuleKind.NetModule;
				return;
			}
			AssemblyDefinition assemblyDefinition = new AssemblyDefinition();
			assemblyDefinition.Name = assemblyNameDefinition;
			module.assembly = assemblyDefinition;
			assemblyDefinition.main_module = module;
		}

		public static ModuleDefinition CreateModule(Image image, ReaderParameters parameters)
		{
			ModuleReader moduleReader = CreateModuleReader(image, parameters.ReadingMode);
			ModuleDefinition moduleDefinition = moduleReader.module;
			if (parameters.assembly_resolver != null)
			{
				moduleDefinition.assembly_resolver = Disposable.NotOwned(parameters.assembly_resolver);
			}
			if (parameters.metadata_resolver != null)
			{
				moduleDefinition.metadata_resolver = parameters.metadata_resolver;
			}
			if (parameters.metadata_importer_provider != null)
			{
				moduleDefinition.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter(moduleDefinition);
			}
			if (parameters.reflection_importer_provider != null)
			{
				moduleDefinition.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter(moduleDefinition);
			}
			GetMetadataKind(moduleDefinition, parameters);
			moduleReader.ReadModule();
			ReadSymbols(moduleDefinition, parameters);
			moduleReader.ReadSymbols(moduleDefinition);
			if (parameters.ReadingMode == ReadingMode.Immediate)
			{
				moduleDefinition.MetadataSystem.Clear();
			}
			return moduleDefinition;
		}

		private static void ReadSymbols(ModuleDefinition module, ReaderParameters parameters)
		{
			ISymbolReaderProvider symbolReaderProvider = parameters.SymbolReaderProvider;
			if (symbolReaderProvider == null && parameters.ReadSymbols)
			{
				symbolReaderProvider = new DefaultSymbolReaderProvider();
			}
			if (symbolReaderProvider != null)
			{
				module.SymbolReaderProvider = symbolReaderProvider;
				ISymbolReader symbolReader = ((parameters.SymbolStream != null) ? symbolReaderProvider.GetSymbolReader(module, parameters.SymbolStream) : symbolReaderProvider.GetSymbolReader(module, module.FileName));
				if (symbolReader != null)
				{
					try
					{
						module.ReadSymbols(symbolReader, parameters.ThrowIfSymbolsAreNotMatching);
					}
					catch (Exception)
					{
						symbolReader.Dispose();
						throw;
					}
				}
			}
			if (module.Image.HasDebugTables())
			{
				module.ReadSymbols(new PortablePdbReader(module.Image, module));
			}
		}

		private static void GetMetadataKind(ModuleDefinition module, ReaderParameters parameters)
		{
			if (!parameters.ApplyWindowsRuntimeProjections)
			{
				module.MetadataKind = MetadataKind.Ecma335;
				return;
			}
			string runtimeVersion = module.RuntimeVersion;
			if (!runtimeVersion.Contains("WindowsRuntime"))
			{
				module.MetadataKind = MetadataKind.Ecma335;
			}
			else if (runtimeVersion.Contains("CLR"))
			{
				module.MetadataKind = MetadataKind.ManagedWindowsMetadata;
			}
			else
			{
				module.MetadataKind = MetadataKind.WindowsMetadata;
			}
		}

		private static ModuleReader CreateModuleReader(Image image, ReadingMode mode)
		{
			return mode switch
			{
				ReadingMode.Immediate => new ImmediateModuleReader(image), 
				ReadingMode.Deferred => new DeferredModuleReader(image), 
				_ => throw new ArgumentException(), 
			};
		}
	}
	internal sealed class ImmediateModuleReader : ModuleReader
	{
		private bool resolve_attributes;

		public ImmediateModuleReader(Image image)
			: base(image, ReadingMode.Immediate)
		{
		}

		protected override void ReadModule()
		{
			module.Read(module, delegate(ModuleDefinition module, MetadataReader reader)
			{
				ReadModuleManifest(reader);
				ReadModule(module, resolve_attributes: true);
			});
		}

		public void ReadModule(ModuleDefinition module, bool resolve_attributes)
		{
			this.resolve_attributes = resolve_attributes;
			if (module.HasAssemblyReferences)
			{
				Mixin.Read(module.AssemblyReferences);
			}
			if (module.HasResources)
			{
				Mixin.Read(module.Resources);
			}
			if (module.HasModuleReferences)
			{
				Mixin.Read(module.ModuleReferences);
			}
			if (module.HasTypes)
			{
				ReadTypes(module.Types);
			}
			if (module.HasExportedTypes)
			{
				Mixin.Read(module.ExportedTypes);
			}
			ReadCustomAttributes(module);
			AssemblyDefinition assembly = module.Assembly;
			if (assembly != null)
			{
				ReadCustomAttributes(assembly);
				ReadSecurityDeclarations(assembly);
			}
		}

		private void ReadTypes(Collection<TypeDefinition> types)
		{
			for (int i = 0; i < types.Count; i++)
			{
				ReadType(types[i]);
			}
		}

		private void ReadType(TypeDefinition type)
		{
			ReadGenericParameters(type);
			if (type.HasInterfaces)
			{
				ReadInterfaces(type);
			}
			if (type.HasNestedTypes)
			{
				ReadTypes(type.NestedTypes);
			}
			if (type.HasLayoutInfo)
			{
				Mixin.Read(type.ClassSize);
			}
			if (type.HasFields)
			{
				ReadFields(type);
			}
			if (type.HasMethods)
			{
				ReadMethods(type);
			}
			if (type.HasProperties)
			{
				ReadProperties(type);
			}
			if (type.HasEvents)
			{
				ReadEvents(type);
			}
			ReadSecurityDeclarations(type);
			ReadCustomAttributes(type);
		}

		private void ReadInterfaces(TypeDefinition type)
		{
			Collection<InterfaceImplementation> interfaces = type.Interfaces;
			for (int i = 0; i < interfaces.Count; i++)
			{
				ReadCustomAttributes(interfaces[i]);
			}
		}

		private void ReadGenericParameters(IGenericParameterProvider provider)
		{
			if (!provider.HasGenericParameters)
			{
				return;
			}
			Collection<GenericParameter> genericParameters = provider.GenericParameters;
			for (int i = 0; i < genericParameters.Count; i++)
			{
				GenericParameter genericParameter = genericParameters[i];
				if (genericParameter.HasConstraints)
				{
					Mixin.Read(genericParameter.Constraints);
				}
				ReadCustomAttributes(genericParameter);
			}
		}

		private void ReadSecurityDeclarations(ISecurityDeclarationProvider provider)
		{
			if (!provider.HasSecurityDeclarations)
			{
				return;
			}
			Collection<SecurityDeclaration> securityDeclarations = provider.SecurityDeclarations;
			if (resolve_attributes)
			{
				for (int i = 0; i < securityDeclarations.Count; i++)
				{
					Mixin.Read(securityDeclarations[i].SecurityAttributes);
				}
			}
		}

		private void ReadCustomAttributes(ICustomAttributeProvider provider)
		{
			if (!provider.HasCustomAttributes)
			{
				return;
			}
			Collection<CustomAttribute> customAttributes = provider.CustomAttributes;
			if (resolve_attributes)
			{
				for (int i = 0; i < customAttributes.Count; i++)
				{
					Mixin.Read(customAttributes[i].ConstructorArguments);
				}
			}
		}

		private void ReadFields(TypeDefinition type)
		{
			Collection<FieldDefinition> fields = type.Fields;
			for (int i = 0; i < fields.Count; i++)
			{
				FieldDefinition fieldDefinition = fields[i];
				if (fieldDefinition.HasConstant)
				{
					Mixin.Read(fieldDefinition.Constant);
				}
				if (fieldDefinition.HasLayoutInfo)
				{
					Mixin.Read(fieldDefinition.Offset);
				}
				if (fieldDefinition.RVA > 0)
				{
					Mixin.Read(fieldDefinition.InitialValue);
				}
				if (fieldDefinition.HasMarshalInfo)
				{
					Mixin.Read(fieldDefinition.MarshalInfo);
				}
				ReadCustomAttributes(fieldDefinition);
			}
		}

		private void ReadMethods(TypeDefinition type)
		{
			Collection<MethodDefinition> methods = type.Methods;
			for (int i = 0; i < methods.Count; i++)
			{
				MethodDefinition methodDefinition = methods[i];
				ReadGenericParameters(methodDefinition);
				if (methodDefinition.HasParameters)
				{
					ReadParameters(methodDefinition);
				}
				if (methodDefinition.HasOverrides)
				{
					Mixin.Read(methodDefinition.Overrides);
				}
				if (methodDefinition.IsPInvokeImpl)
				{
					Mixin.Read(methodDefinition.PInvokeInfo);
				}
				ReadSecurityDeclarations(methodDefinition);
				ReadCustomAttributes(methodDefinition);
				MethodReturnType methodReturnType = methodDefinition.MethodReturnType;
				if (methodReturnType.HasConstant)
				{
					Mixin.Read(methodReturnType.Constant);
				}
				if (methodReturnType.HasMarshalInfo)
				{
					Mixin.Read(methodReturnType.MarshalInfo);
				}
				ReadCustomAttributes(methodReturnType);
			}
		}

		private void ReadParameters(MethodDefinition method)
		{
			Collection<ParameterDefinition> parameters = method.Parameters;
			for (int i = 0; i < parameters.Count; i++)
			{
				ParameterDefinition parameterDefinition = parameters[i];
				if (parameterDefinition.HasConstant)
				{
					Mixin.Read(parameterDefinition.Constant);
				}
				if (parameterDefinition.HasMarshalInfo)
				{
					Mixin.Read(parameterDefinition.MarshalInfo);
				}
				ReadCustomAttributes(parameterDefinition);
			}
		}

		private void ReadProperties(TypeDefinition type)
		{
			Collection<PropertyDefinition> properties = type.Properties;
			for (int i = 0; i < properties.Count; i++)
			{
				PropertyDefinition propertyDefinition = properties[i];
				Mixin.Read(propertyDefinition.GetMethod);
				if (propertyDefinition.HasConstant)
				{
					Mixin.Read(propertyDefinition.Constant);
				}
				ReadCustomAttributes(propertyDefinition);
			}
		}

		private void ReadEvents(TypeDefinition type)
		{
			Collection<EventDefinition> events = type.Events;
			for (int i = 0; i < events.Count; i++)
			{
				EventDefinition eventDefinition = events[i];
				Mixin.Read(eventDefinition.AddMethod);
				ReadCustomAttributes(eventDefinition);
			}
		}

		public override void ReadSymbols(ModuleDefinition module)
		{
			if (module.symbol_reader != null)
			{
				ReadTypesSymbols(module.Types, module.symbol_reader);
			}
		}

		private void ReadTypesSymbols(Collection<TypeDefinition> types, ISymbolReader symbol_reader)
		{
			for (int i = 0; i < types.Count; i++)
			{
				TypeDefinition typeDefinition = types[i];
				if (typeDefinition.HasNestedTypes)
				{
					ReadTypesSymbols(typeDefinition.NestedTypes, symbol_reader);
				}
				if (typeDefinition.HasMethods)
				{
					ReadMethodsSymbols(typeDefinition, symbol_reader);
				}
			}
		}

		private void ReadMethodsSymbols(TypeDefinition type, ISymbolReader symbol_reader)
		{
			Collection<MethodDefinition> methods = type.Methods;
			for (int i = 0; i < methods.Count; i++)
			{
				MethodDefinition methodDefinition = methods[i];
				if (methodDefinition.HasBody && methodDefinition.token.RID != 0 && methodDefinition.debug_info == null)
				{
					methodDefinition.debug_info = symbol_reader.Read(methodDefinition);
				}
			}
		}
	}
	internal sealed class DeferredModuleReader : ModuleReader
	{
		public DeferredModuleReader(Image image)
			: base(image, ReadingMode.Deferred)
		{
		}

		protected override void ReadModule()
		{
			module.Read(module, delegate(ModuleDefinition _, MetadataReader reader)
			{
				ReadModuleManifest(reader);
			});
		}

		public override void ReadSymbols(ModuleDefinition module)
		{
		}
	}
	internal sealed class MetadataReader : ByteBuffer
	{
		internal readonly Image image;

		internal readonly ModuleDefinition module;

		internal readonly MetadataSystem metadata;

		internal CodeReader code;

		internal IGenericContext context;

		private readonly MetadataReader metadata_reader;

		public MetadataReader(ModuleDefinition module)
			: base(module.Image.TableHeap.data)
		{
			image = module.Image;
			this.module = module;
			metadata = module.MetadataSystem;
			code = new CodeReader(this);
		}

		public MetadataReader(Image image, ModuleDefinition module, MetadataReader metadata_reader)
			: base(image.TableHeap.data)
		{
			this.image = image;
			this.module = module;
			metadata = module.MetadataSystem;
			this.metadata_reader = metadata_reader;
		}

		private int GetCodedIndexSize(CodedIndex index)
		{
			return image.GetCodedIndexSize(index);
		}

		private uint ReadByIndexSize(int size)
		{
			if (size == 4)
			{
				return ReadUInt32();
			}
			return ReadUInt16();
		}

		private byte[] ReadBlob()
		{
			BlobHeap blobHeap = image.BlobHeap;
			if (blobHeap == null)
			{
				position += 2;
				return Empty<byte>.Array;
			}
			return blobHeap.Read(ReadBlobIndex());
		}

		private byte[] ReadBlob(uint signature)
		{
			BlobHeap blobHeap = image.BlobHeap;
			if (blobHeap == null)
			{
				return Empty<byte>.Array;
			}
			return blobHeap.Read(signature);
		}

		private uint ReadBlobIndex()
		{
			return ReadByIndexSize(image.BlobHeap?.IndexSize ?? 2);
		}

		private void GetBlobView(uint signature, out byte[] blob, out int index, out int count)
		{
			BlobHeap blobHeap = image.BlobHeap;
			if (blobHeap == null)
			{
				blob = null;
				index = (count = 0);
			}
			else
			{
				blobHeap.GetView(signature, out blob, out index, out count);
			}
		}

		private string ReadString()
		{
			return image.StringHeap.Read(ReadByIndexSize(image.StringHeap.IndexSize));
		}

		private uint ReadStringIndex()
		{
			return ReadByIndexSize(image.StringHeap.IndexSize);
		}

		private Guid ReadGuid()
		{
			return image.GuidHeap.Read(ReadByIndexSize(image.GuidHeap.IndexSize));
		}

		private uint ReadTableIndex(Table table)
		{
			return ReadByIndexSize(image.GetTableIndexSize(table));
		}

		private MetadataToken ReadMetadataToken(CodedIndex index)
		{
			return index.GetMetadataToken(ReadByIndexSize(GetCodedIndexSize(index)));
		}

		private int MoveTo(Table table)
		{
			TableInformation tableInformation = image.TableHeap[table];
			if (tableInformation.Length != 0)
			{
				position = (int)tableInformation.Offset;
			}
			return (int)tableInformation.Length;
		}

		private bool MoveTo(Table table, uint row)
		{
			TableInformation tableInformation = image.TableHeap[table];
			uint num = tableInformation.Length;
			if (num == 0 || row > num)
			{
				return false;
			}
			position = (int)(tableInformation.Offset + tableInformation.RowSize * (row - 1));
			return true;
		}

		public AssemblyNameDefinition ReadAssemblyNameDefinition()
		{
			if (MoveTo(Table.Assembly) == 0)
			{
				return null;
			}
			AssemblyNameDefinition assemblyNameDefinition = new AssemblyNameDefinition();
			assemblyNameDefinition.HashAlgorithm = (AssemblyHashAlgorithm)ReadUInt32();
			PopulateVersionAndFlags(assemblyNameDefinition);
			assemblyNameDefinition.PublicKey = ReadBlob();
			PopulateNameAndCulture(assemblyNameDefinition);
			return assemblyNameDefinition;
		}

		public ModuleDefinition Populate(ModuleDefinition module)
		{
			if (MoveTo(Table.Module) == 0)
			{
				return module;
			}
			Advance(2);
			module.Name = ReadString();
			module.Mvid = ReadGuid();
			return module;
		}

		private void InitializeAssemblyReferences()
		{
			if (metadata.AssemblyReferences != null)
			{
				return;
			}
			int num = MoveTo(Table.AssemblyRef);
			AssemblyNameReference[] array = (metadata.AssemblyReferences = new AssemblyNameReference[num]);
			for (uint num2 = 0u; num2 < num; num2++)
			{
				AssemblyNameReference assemblyNameReference = new AssemblyNameReference();
				assemblyNameReference.token = new MetadataToken(TokenType.AssemblyRef, num2 + 1);
				PopulateVersionAndFlags(assemblyNameReference);
				byte[] array2 = ReadBlob();
				if (assemblyNameReference.HasPublicKey)
				{
					assemblyNameReference.PublicKey = array2;
				}
				else
				{
					assemblyNameReference.PublicKeyToken = array2;
				}
				PopulateNameAndCulture(assemblyNameReference);
				assemblyNameReference.Hash = ReadBlob();
				array[num2] = assemblyNameReference;
			}
		}

		public Collection<AssemblyNameReference> ReadAssemblyReferences()
		{
			InitializeAssemblyReferences();
			Collection<AssemblyNameReference> collection = new Collection<AssemblyNameReference>(metadata.AssemblyReferences);
			if (module.IsWindowsMetadata())
			{
				module.Projections.AddVirtualReferences(collection);
			}
			return collection;
		}

		public MethodDefinition ReadEntryPoint()
		{
			if (module.Image.EntryPointToken == 0)
			{
				return null;
			}
			return GetMethodDefinition(new MetadataToken(module.Image.EntryPointToken).RID);
		}

		public Collection<ModuleDefinition> ReadModules()
		{
			Collection<ModuleDefinition> collection = new Collection<ModuleDefinition>(1);
			collection.Add(module);
			int num = MoveTo(Table.File);
			for (uint num2 = 1u; num2 <= num; num2++)
			{
				uint num3 = ReadUInt32();
				string name = ReadString();
				ReadBlobIndex();
				if (num3 == 0)
				{
					ReaderParameters parameters = new ReaderParameters
					{
						ReadingMode = module.ReadingMode,
						SymbolReaderProvider = module.SymbolReaderProvider,
						AssemblyResolver = module.AssemblyResolver
					};
					collection.Add(ModuleDefinition.ReadModule(GetModuleFileName(name), parameters));
				}
			}
			return collection;
		}

		private string GetModuleFileName(string name)
		{
			if (module.FileName == null)
			{
				throw new NotSupportedException();
			}
			return Path.Combine(Path.GetDirectoryName(module.FileName), name);
		}

		private void InitializeModuleReferences()
		{
			if (metadata.ModuleReferences == null)
			{
				int num = MoveTo(Table.ModuleRef);
				ModuleReference[] array = (metadata.ModuleReferences = new ModuleReference[num]);
				for (uint num2 = 0u; num2 < num; num2++)
				{
					ModuleReference moduleReference = new ModuleReference(ReadString());
					moduleReference.token = new MetadataToken(TokenType.ModuleRef, num2 + 1);
					array[num2] = moduleReference;
				}
			}
		}

		public Collection<ModuleReference> ReadModuleReferences()
		{
			InitializeModuleReferences();
			return new Collection<ModuleReference>(metadata.ModuleReferences);
		}

		public bool HasFileResource()
		{
			int num = MoveTo(Table.File);
			if (num == 0)
			{
				return false;
			}
			for (uint num2 = 1u; num2 <= num; num2++)
			{
				if (ReadFileRecord(num2).Col1 == FileAttributes.ContainsNoMetaData)
				{
					return true;
				}
			}
			return false;
		}

		public Collection<Resource> ReadResources()
		{
			int num = MoveTo(Table.ManifestResource);
			Collection<Resource> collection = new Collection<Resource>(num);
			for (int i = 1; i <= num; i++)
			{
				uint offset = ReadUInt32();
				ManifestResourceAttributes manifestResourceAttributes = (ManifestResourceAttributes)ReadUInt32();
				string name = ReadString();
				MetadataToken scope = ReadMetadataToken(CodedIndex.Implementation);
				Resource item;
				if (scope.RID == 0)
				{
					item = new EmbeddedResource(name, manifestResourceAttributes, offset, this);
				}
				else if (scope.TokenType == TokenType.AssemblyRef)
				{
					item = new AssemblyLinkedResource(name, manifestResourceAttributes)
					{
						Assembly = (AssemblyNameReference)GetTypeReferenceScope(scope)
					};
				}
				else
				{
					if (scope.TokenType != TokenType.File)
					{
						continue;
					}
					Row<FileAttributes, string, uint> row = ReadFileRecord(scope.RID);
					item = new LinkedResource(name, manifestResourceAttributes)
					{
						File = row.Col2,
						hash = ReadBlob(row.Col3)
					};
				}
				collection.Add(item);
			}
			return collection;
		}

		private Row<FileAttributes, string, uint> ReadFileRecord(uint rid)
		{
			int num = position;
			if (!MoveTo(Table.File, rid))
			{
				throw new ArgumentException();
			}
			Row<FileAttributes, string, uint> result = new Row<FileAttributes, string, uint>((FileAttributes)ReadUInt32(), ReadString(), ReadBlobIndex());
			position = num;
			return result;
		}

		public byte[] GetManagedResource(uint offset)
		{
			return image.GetReaderAt(image.Resources.VirtualAddress, offset, delegate(uint o, BinaryStreamReader reader)
			{
				reader.Advance((int)o);
				return reader.ReadBytes(reader.ReadInt32());
			}) ?? Empty<byte>.Array;
		}

		private void PopulateVersionAndFlags(AssemblyNameReference name)
		{
			name.Version = new Version(ReadUInt16(), ReadUInt16(), ReadUInt16(), ReadUInt16());
			name.Attributes = (AssemblyAttributes)ReadUInt32();
		}

		private void PopulateNameAndCulture(AssemblyNameReference name)
		{
			name.Name = ReadString();
			name.Culture = ReadString();
		}

		public TypeDefinitionCollection ReadTypes()
		{
			InitializeTypeDefinitions();
			TypeDefinition[] types = metadata.Types;
			int capacity = types.Length - metadata.NestedTypes.Count;
			TypeDefinitionCollection typeDefinitionCollection = new TypeDefinitionCollection(module, capacity);
			foreach (TypeDefinition typeDefinition in types)
			{
				if (!IsNested(typeDefinition.Attributes))
				{
					typeDefinitionCollection.Add(typeDefinition);
				}
			}
			if (image.HasTable(Table.MethodPtr) || image.HasTable(Table.FieldPtr))
			{
				CompleteTypes();
			}
			return typeDefinitionCollection;
		}

		private void CompleteTypes()
		{
			TypeDefinition[] types = metadata.Types;
			foreach (TypeDefinition obj in types)
			{
				Mixin.Read(obj.Fields);
				Mixin.Read(obj.Methods);
			}
		}

		private void InitializeTypeDefinitions()
		{
			if (metadata.Types != null)
			{
				return;
			}
			InitializeNestedTypes();
			InitializeFields();
			InitializeMethods();
			int num = MoveTo(Table.TypeDef);
			TypeDefinition[] array = (metadata.Types = new TypeDefinition[num]);
			for (uint num2 = 0u; num2 < num; num2++)
			{
				if (array[num2] == null)
				{
					array[num2] = ReadType(num2 + 1);
				}
			}
			if (module.IsWindowsMetadata())
			{
				for (uint num3 = 0u; num3 < num; num3++)
				{
					WindowsRuntimeProjections.Project(array[num3]);
				}
			}
		}

		private static bool IsNested(TypeAttributes attributes)
		{
			switch (attributes & TypeAttributes.VisibilityMask)
			{
			case TypeAttributes.NestedPublic:
			case TypeAttributes.NestedPrivate:
			case TypeAttributes.NestedFamily:
			case TypeAttributes.NestedAssembly:
			case TypeAttributes.NestedFamANDAssem:
			case TypeAttributes.VisibilityMask:
				return true;
			default:
				return false;
			}
		}

		public bool HasNestedTypes(TypeDefinition type)
		{
			InitializeNestedTypes();
			if (!metadata.TryGetNestedTypeMapping(type, out var mapping))
			{
				return false;
			}
			return mapping.Count > 0;
		}

		public Collection<TypeDefinition> ReadNestedTypes(TypeDefinition type)
		{
			InitializeNestedTypes();
			if (!metadata.TryGetNestedTypeMapping(type, out var mapping))
			{
				return new MemberDefinitionCollection<TypeDefinition>(type);
			}
			MemberDefinitionCollection<TypeDefinition> memberDefinitionCollection = new MemberDefinitionCollection<TypeDefinition>(type, mapping.Count);
			for (int i = 0; i < mapping.Count; i++)
			{
				TypeDefinition typeDefinition = GetTypeDefinition(mapping[i]);
				if (typeDefinition != null)
				{
					memberDefinitionCollection.Add(typeDefinition);
				}
			}
			metadata.RemoveNestedTypeMapping(type);
			return memberDefinitionCollection;
		}

		private void InitializeNestedTypes()
		{
			if (metadata.NestedTypes != null)
			{
				return;
			}
			int num = MoveTo(Table.NestedClass);
			metadata.NestedTypes = new Dictionary<uint, Collection<uint>>(num);
			metadata.ReverseNestedTypes = new Dictionary<uint, uint>(num);
			if (num != 0)
			{
				for (int i = 1; i <= num; i++)
				{
					uint nested = ReadTableIndex(Table.TypeDef);
					uint declaring = ReadTableIndex(Table.TypeDef);
					AddNestedMapping(declaring, nested);
				}
			}
		}

		private void AddNestedMapping(uint declaring, uint nested)
		{
			metadata.SetNestedTypeMapping(declaring, AddMapping(metadata.NestedTypes, declaring, nested));
			metadata.SetReverseNestedTypeMapping(nested, declaring);
		}

		private static Collection<TValue> AddMapping<TKey, TValue>(Dictionary<TKey, Collection<TValue>> cache, TKey key, TValue value)
		{
			if (!cache.TryGetValue(key, out var value2))
			{
				value2 = new Collection<TValue>();
			}
			value2.Add(value);
			return value2;
		}

		private TypeDefinition ReadType(uint rid)
		{
			if (!MoveTo(Table.TypeDef, rid))
			{
				return null;
			}
			TypeAttributes attributes = (TypeAttributes)ReadUInt32();
			string name = ReadString();
			TypeDefinition typeDefinition = new TypeDefinition(ReadString(), name, attributes);
			typeDefinition.token = new MetadataToken(TokenType.TypeDef, rid);
			typeDefinition.scope = module;
			typeDefinition.module = module;
			metadata.AddTypeDefinition(typeDefinition);
			context = typeDefinition;
			typeDefinition.BaseType = GetTypeDefOrRef(ReadMetadataToken(CodedIndex.TypeDefOrRef));
			typeDefinition.fields_range = ReadListRange(rid, Table.TypeDef, Table.Field);
			typeDefinition.methods_range = ReadListRange(rid, Table.TypeDef, Table.Method);
			if (IsNested(attributes))
			{
				typeDefinition.DeclaringType = GetNestedTypeDeclaringType(typeDefinition);
			}
			return typeDefinition;
		}

		private TypeDefinition GetNestedTypeDeclaringType(TypeDefinition type)
		{
			if (!metadata.TryGetReverseNestedTypeMapping(type, out var declaring))
			{
				return null;
			}
			metadata.RemoveReverseNestedTypeMapping(type);
			return GetTypeDefinition(declaring);
		}

		private Range ReadListRange(uint current_index, Table current, Table target)
		{
			Range result = default(Range);
			uint num = ReadTableIndex(target);
			if (num == 0)
			{
				return result;
			}
			TableInformation tableInformation = image.TableHeap[current];
			uint num2;
			if (current_index == tableInformation.Length)
			{
				num2 = image.TableHeap[target].Length + 1;
			}
			else
			{
				int num3 = position;
				position += (int)(tableInformation.RowSize - image.GetTableIndexSize(target));
				num2 = ReadTableIndex(target);
				position = num3;
			}
			result.Start = num;
			result.Length = num2 - num;
			return result;
		}

		public Row<short, int> ReadTypeLayout(TypeDefinition type)
		{
			InitializeTypeLayouts();
			uint rID = type.token.RID;
			if (!metadata.ClassLayouts.TryGetValue(rID, out var value))
			{
				return new Row<short, int>(-1, -1);
			}
			type.PackingSize = (short)value.Col1;
			type.ClassSize = (int)value.Col2;
			metadata.ClassLayouts.Remove(rID);
			return new Row<short, int>((short)value.Col1, (int)value.Col2);
		}

		private void InitializeTypeLayouts()
		{
			if (metadata.ClassLayouts == null)
			{
				int num = MoveTo(Table.ClassLayout);
				Dictionary<uint, Row<ushort, uint>> dictionary = (metadata.ClassLayouts = new Dictionary<uint, Row<ushort, uint>>(num));
				for (uint num2 = 0u; 

BepInEx/core/Mono.Cecil.Mdb.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using Mono.CompilerServices.SymbolWriter;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("Mono.Cecil")]
[assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("0.10.4.0")]
[assembly: AssemblyInformationalVersion("0.10.4.0")]
[assembly: AssemblyTitle("Mono.Cecil.Mdb")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyVersion("0.10.4.0")]
namespace Mono.CompilerServices.SymbolWriter
{
	public class MonoSymbolFileException : Exception
	{
		public MonoSymbolFileException()
		{
		}

		public MonoSymbolFileException(string message, params object[] args)
			: base(string.Format(message, args))
		{
		}

		public MonoSymbolFileException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	internal sealed class MyBinaryWriter : BinaryWriter
	{
		public MyBinaryWriter(Stream stream)
			: base(stream)
		{
		}

		public void WriteLeb128(int value)
		{
			Write7BitEncodedInt(value);
		}
	}
	internal class MyBinaryReader : BinaryReader
	{
		public MyBinaryReader(Stream stream)
			: base(stream)
		{
		}

		public int ReadLeb128()
		{
			return Read7BitEncodedInt();
		}

		public string ReadString(int offset)
		{
			long position = BaseStream.Position;
			BaseStream.Position = offset;
			string result = ReadString();
			BaseStream.Position = position;
			return result;
		}
	}
	public interface ISourceFile
	{
		SourceFileEntry Entry { get; }
	}
	public interface ICompileUnit
	{
		CompileUnitEntry Entry { get; }
	}
	public interface IMethodDef
	{
		string Name { get; }

		int Token { get; }
	}
	public class MonoSymbolFile : IDisposable
	{
		private List<MethodEntry> methods = new List<MethodEntry>();

		private List<SourceFileEntry> sources = new List<SourceFileEntry>();

		private List<CompileUnitEntry> comp_units = new List<CompileUnitEntry>();

		private Dictionary<int, AnonymousScopeEntry> anonymous_scopes;

		private OffsetTable ot;

		private int last_type_index;

		private int last_method_index;

		private int last_namespace_index;

		public readonly int MajorVersion = 50;

		public readonly int MinorVersion;

		public int NumLineNumbers;

		private MyBinaryReader reader;

		private Dictionary<int, SourceFileEntry> source_file_hash;

		private Dictionary<int, CompileUnitEntry> compile_unit_hash;

		private List<MethodEntry> method_list;

		private Dictionary<int, MethodEntry> method_token_hash;

		private Dictionary<string, int> source_name_hash;

		private Guid guid;

		internal int LineNumberCount;

		internal int LocalCount;

		internal int StringSize;

		internal int LineNumberSize;

		internal int ExtendedLineNumberSize;

		public int CompileUnitCount => ot.CompileUnitCount;

		public int SourceCount => ot.SourceCount;

		public int MethodCount => ot.MethodCount;

		public int TypeCount => ot.TypeCount;

		public int AnonymousScopeCount => ot.AnonymousScopeCount;

		public int NamespaceCount => last_namespace_index;

		public Guid Guid => guid;

		public OffsetTable OffsetTable => ot;

		public SourceFileEntry[] Sources
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException();
				}
				SourceFileEntry[] array = new SourceFileEntry[SourceCount];
				for (int i = 0; i < SourceCount; i++)
				{
					array[i] = GetSourceFile(i + 1);
				}
				return array;
			}
		}

		public CompileUnitEntry[] CompileUnits
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException();
				}
				CompileUnitEntry[] array = new CompileUnitEntry[CompileUnitCount];
				for (int i = 0; i < CompileUnitCount; i++)
				{
					array[i] = GetCompileUnit(i + 1);
				}
				return array;
			}
		}

		public MethodEntry[] Methods
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException();
				}
				lock (this)
				{
					read_methods();
					MethodEntry[] array = new MethodEntry[MethodCount];
					method_list.CopyTo(array, 0);
					return array;
				}
			}
		}

		internal MyBinaryReader BinaryReader
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException();
				}
				return reader;
			}
		}

		public MonoSymbolFile()
		{
			ot = new OffsetTable();
		}

		public int AddSource(SourceFileEntry source)
		{
			sources.Add(source);
			return sources.Count;
		}

		public int AddCompileUnit(CompileUnitEntry entry)
		{
			comp_units.Add(entry);
			return comp_units.Count;
		}

		public void AddMethod(MethodEntry entry)
		{
			methods.Add(entry);
		}

		public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id)
		{
			if (reader != null)
			{
				throw new InvalidOperationException();
			}
			MethodEntry methodEntry = new MethodEntry(this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id);
			AddMethod(methodEntry);
			return methodEntry;
		}

		internal void DefineAnonymousScope(int id)
		{
			if (reader != null)
			{
				throw new InvalidOperationException();
			}
			if (anonymous_scopes == null)
			{
				anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>();
			}
			anonymous_scopes.Add(id, new AnonymousScopeEntry(id));
		}

		internal void DefineCapturedVariable(int scope_id, string name, string captured_name, CapturedVariable.CapturedKind kind)
		{
			if (reader != null)
			{
				throw new InvalidOperationException();
			}
			anonymous_scopes[scope_id].AddCapturedVariable(name, captured_name, kind);
		}

		internal void DefineCapturedScope(int scope_id, int id, string captured_name)
		{
			if (reader != null)
			{
				throw new InvalidOperationException();
			}
			anonymous_scopes[scope_id].AddCapturedScope(id, captured_name);
		}

		internal int GetNextTypeIndex()
		{
			return ++last_type_index;
		}

		internal int GetNextMethodIndex()
		{
			return ++last_method_index;
		}

		internal int GetNextNamespaceIndex()
		{
			return ++last_namespace_index;
		}

		private void Write(MyBinaryWriter bw, Guid guid)
		{
			bw.Write(5037318119232611860L);
			bw.Write(MajorVersion);
			bw.Write(MinorVersion);
			bw.Write(guid.ToByteArray());
			long position = bw.BaseStream.Position;
			ot.Write(bw, MajorVersion, MinorVersion);
			methods.Sort();
			for (int i = 0; i < methods.Count; i++)
			{
				methods[i].Index = i + 1;
			}
			ot.DataSectionOffset = (int)bw.BaseStream.Position;
			foreach (SourceFileEntry source in sources)
			{
				source.WriteData(bw);
			}
			foreach (CompileUnitEntry comp_unit in comp_units)
			{
				comp_unit.WriteData(bw);
			}
			foreach (MethodEntry method in methods)
			{
				method.WriteData(this, bw);
			}
			ot.DataSectionSize = (int)bw.BaseStream.Position - ot.DataSectionOffset;
			ot.MethodTableOffset = (int)bw.BaseStream.Position;
			for (int j = 0; j < methods.Count; j++)
			{
				methods[j].Write(bw);
			}
			ot.MethodTableSize = (int)bw.BaseStream.Position - ot.MethodTableOffset;
			ot.SourceTableOffset = (int)bw.BaseStream.Position;
			for (int k = 0; k < sources.Count; k++)
			{
				sources[k].Write(bw);
			}
			ot.SourceTableSize = (int)bw.BaseStream.Position - ot.SourceTableOffset;
			ot.CompileUnitTableOffset = (int)bw.BaseStream.Position;
			for (int l = 0; l < comp_units.Count; l++)
			{
				comp_units[l].Write(bw);
			}
			ot.CompileUnitTableSize = (int)bw.BaseStream.Position - ot.CompileUnitTableOffset;
			ot.AnonymousScopeCount = ((anonymous_scopes != null) ? anonymous_scopes.Count : 0);
			ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position;
			if (anonymous_scopes != null)
			{
				foreach (AnonymousScopeEntry value in anonymous_scopes.Values)
				{
					value.Write(bw);
				}
			}
			ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - ot.AnonymousScopeTableOffset;
			ot.TypeCount = last_type_index;
			ot.MethodCount = methods.Count;
			ot.SourceCount = sources.Count;
			ot.CompileUnitCount = comp_units.Count;
			ot.TotalFileSize = (int)bw.BaseStream.Position;
			bw.Seek((int)position, SeekOrigin.Begin);
			ot.Write(bw, MajorVersion, MinorVersion);
			bw.Seek(0, SeekOrigin.End);
		}

		public void CreateSymbolFile(Guid guid, FileStream fs)
		{
			if (reader != null)
			{
				throw new InvalidOperationException();
			}
			Write(new MyBinaryWriter(fs), guid);
		}

		private MonoSymbolFile(Stream stream)
		{
			reader = new MyBinaryReader(stream);
			try
			{
				long num = reader.ReadInt64();
				int num2 = reader.ReadInt32();
				int num3 = reader.ReadInt32();
				if (num != 5037318119232611860L)
				{
					throw new MonoSymbolFileException("Symbol file is not a valid");
				}
				if (num2 != 50)
				{
					throw new MonoSymbolFileException("Symbol file has version {0} but expected {1}", num2, 50);
				}
				if (num3 != 0)
				{
					throw new MonoSymbolFileException("Symbol file has version {0}.{1} but expected {2}.{3}", num2, num3, 50, 0);
				}
				MajorVersion = num2;
				MinorVersion = num3;
				guid = new Guid(reader.ReadBytes(16));
				ot = new OffsetTable(reader, num2, num3);
			}
			catch (Exception innerException)
			{
				throw new MonoSymbolFileException("Cannot read symbol file", innerException);
			}
			source_file_hash = new Dictionary<int, SourceFileEntry>();
			compile_unit_hash = new Dictionary<int, CompileUnitEntry>();
		}

		public static MonoSymbolFile ReadSymbolFile(Assembly assembly)
		{
			string mdbFilename = assembly.Location + ".mdb";
			Guid moduleVersionId = assembly.GetModules()[0].ModuleVersionId;
			return ReadSymbolFile(mdbFilename, moduleVersionId);
		}

		public static MonoSymbolFile ReadSymbolFile(string mdbFilename)
		{
			return ReadSymbolFile(new FileStream(mdbFilename, FileMode.Open, FileAccess.Read));
		}

		public static MonoSymbolFile ReadSymbolFile(string mdbFilename, Guid assemblyGuid)
		{
			MonoSymbolFile monoSymbolFile = ReadSymbolFile(mdbFilename);
			if (assemblyGuid != monoSymbolFile.guid)
			{
				throw new MonoSymbolFileException("Symbol file `{0}' does not match assembly", mdbFilename);
			}
			return monoSymbolFile;
		}

		public static MonoSymbolFile ReadSymbolFile(Stream stream)
		{
			return new MonoSymbolFile(stream);
		}

		public SourceFileEntry GetSourceFile(int index)
		{
			if (index < 1 || index > ot.SourceCount)
			{
				throw new ArgumentException();
			}
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				if (source_file_hash.TryGetValue(index, out var value))
				{
					return value;
				}
				long position = reader.BaseStream.Position;
				reader.BaseStream.Position = ot.SourceTableOffset + SourceFileEntry.Size * (index - 1);
				value = new SourceFileEntry(this, reader);
				source_file_hash.Add(index, value);
				reader.BaseStream.Position = position;
				return value;
			}
		}

		public CompileUnitEntry GetCompileUnit(int index)
		{
			if (index < 1 || index > ot.CompileUnitCount)
			{
				throw new ArgumentException();
			}
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				if (compile_unit_hash.TryGetValue(index, out var value))
				{
					return value;
				}
				long position = reader.BaseStream.Position;
				reader.BaseStream.Position = ot.CompileUnitTableOffset + CompileUnitEntry.Size * (index - 1);
				value = new CompileUnitEntry(this, reader);
				compile_unit_hash.Add(index, value);
				reader.BaseStream.Position = position;
				return value;
			}
		}

		private void read_methods()
		{
			lock (this)
			{
				if (method_token_hash == null)
				{
					method_token_hash = new Dictionary<int, MethodEntry>();
					method_list = new List<MethodEntry>();
					long position = reader.BaseStream.Position;
					reader.BaseStream.Position = ot.MethodTableOffset;
					for (int i = 0; i < MethodCount; i++)
					{
						MethodEntry methodEntry = new MethodEntry(this, reader, i + 1);
						method_token_hash.Add(methodEntry.Token, methodEntry);
						method_list.Add(methodEntry);
					}
					reader.BaseStream.Position = position;
				}
			}
		}

		public MethodEntry GetMethodByToken(int token)
		{
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				read_methods();
				method_token_hash.TryGetValue(token, out var value);
				return value;
			}
		}

		public MethodEntry GetMethod(int index)
		{
			if (index < 1 || index > ot.MethodCount)
			{
				throw new ArgumentException();
			}
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				read_methods();
				return method_list[index - 1];
			}
		}

		public int FindSource(string file_name)
		{
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				if (source_name_hash == null)
				{
					source_name_hash = new Dictionary<string, int>();
					for (int i = 0; i < ot.SourceCount; i++)
					{
						SourceFileEntry sourceFile = GetSourceFile(i + 1);
						source_name_hash.Add(sourceFile.FileName, i);
					}
				}
				if (!source_name_hash.TryGetValue(file_name, out var value))
				{
					return -1;
				}
				return value;
			}
		}

		public AnonymousScopeEntry GetAnonymousScope(int id)
		{
			if (reader == null)
			{
				throw new InvalidOperationException();
			}
			lock (this)
			{
				if (anonymous_scopes != null)
				{
					anonymous_scopes.TryGetValue(id, out var value);
					return value;
				}
				anonymous_scopes = new Dictionary<int, AnonymousScopeEntry>();
				reader.BaseStream.Position = ot.AnonymousScopeTableOffset;
				for (int i = 0; i < ot.AnonymousScopeCount; i++)
				{
					AnonymousScopeEntry value = new AnonymousScopeEntry(reader);
					anonymous_scopes.Add(value.ID, value);
				}
				return anonymous_scopes[id];
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (disposing && reader != null)
			{
				reader.Close();
				reader = null;
			}
		}
	}
	public class OffsetTable
	{
		[Flags]
		public enum Flags
		{
			IsAspxSource = 1,
			WindowsFileNames = 2
		}

		public const int MajorVersion = 50;

		public const int MinorVersion = 0;

		public const long Magic = 5037318119232611860L;

		public int TotalFileSize;

		public int DataSectionOffset;

		public int DataSectionSize;

		public int CompileUnitCount;

		public int CompileUnitTableOffset;

		public int CompileUnitTableSize;

		public int SourceCount;

		public int SourceTableOffset;

		public int SourceTableSize;

		public int MethodCount;

		public int MethodTableOffset;

		public int MethodTableSize;

		public int TypeCount;

		public int AnonymousScopeCount;

		public int AnonymousScopeTableOffset;

		public int AnonymousScopeTableSize;

		public Flags FileFlags;

		public int LineNumberTable_LineBase = -1;

		public int LineNumberTable_LineRange = 8;

		public int LineNumberTable_OpcodeBase = 9;

		internal OffsetTable()
		{
			int platform = (int)Environment.OSVersion.Platform;
			if (platform != 4 && platform != 128)
			{
				FileFlags |= Flags.WindowsFileNames;
			}
		}

		internal OffsetTable(BinaryReader reader, int major_version, int minor_version)
		{
			TotalFileSize = reader.ReadInt32();
			DataSectionOffset = reader.ReadInt32();
			DataSectionSize = reader.ReadInt32();
			CompileUnitCount = reader.ReadInt32();
			CompileUnitTableOffset = reader.ReadInt32();
			CompileUnitTableSize = reader.ReadInt32();
			SourceCount = reader.ReadInt32();
			SourceTableOffset = reader.ReadInt32();
			SourceTableSize = reader.ReadInt32();
			MethodCount = reader.ReadInt32();
			MethodTableOffset = reader.ReadInt32();
			MethodTableSize = reader.ReadInt32();
			TypeCount = reader.ReadInt32();
			AnonymousScopeCount = reader.ReadInt32();
			AnonymousScopeTableOffset = reader.ReadInt32();
			AnonymousScopeTableSize = reader.ReadInt32();
			LineNumberTable_LineBase = reader.ReadInt32();
			LineNumberTable_LineRange = reader.ReadInt32();
			LineNumberTable_OpcodeBase = reader.ReadInt32();
			FileFlags = (Flags)reader.ReadInt32();
		}

		internal void Write(BinaryWriter bw, int major_version, int minor_version)
		{
			bw.Write(TotalFileSize);
			bw.Write(DataSectionOffset);
			bw.Write(DataSectionSize);
			bw.Write(CompileUnitCount);
			bw.Write(CompileUnitTableOffset);
			bw.Write(CompileUnitTableSize);
			bw.Write(SourceCount);
			bw.Write(SourceTableOffset);
			bw.Write(SourceTableSize);
			bw.Write(MethodCount);
			bw.Write(MethodTableOffset);
			bw.Write(MethodTableSize);
			bw.Write(TypeCount);
			bw.Write(AnonymousScopeCount);
			bw.Write(AnonymousScopeTableOffset);
			bw.Write(AnonymousScopeTableSize);
			bw.Write(LineNumberTable_LineBase);
			bw.Write(LineNumberTable_LineRange);
			bw.Write(LineNumberTable_OpcodeBase);
			bw.Write((int)FileFlags);
		}

		public override string ToString()
		{
			return $"OffsetTable [{TotalFileSize} - {DataSectionOffset}:{DataSectionSize} - {SourceCount}:{SourceTableOffset}:{SourceTableSize} - {MethodCount}:{MethodTableOffset}:{MethodTableSize} - {TypeCount}]";
		}
	}
	public class LineNumberEntry
	{
		public sealed class LocationComparer : IComparer<LineNumberEntry>
		{
			public static readonly LocationComparer Default = new LocationComparer();

			public int Compare(LineNumberEntry l1, LineNumberEntry l2)
			{
				if (l1.Row != l2.Row)
				{
					int row = l1.Row;
					return row.CompareTo(l2.Row);
				}
				return l1.Column.CompareTo(l2.Column);
			}
		}

		public readonly int Row;

		public int Column;

		public int EndRow;

		public int EndColumn;

		public readonly int File;

		public readonly int Offset;

		public readonly bool IsHidden;

		public static readonly LineNumberEntry Null = new LineNumberEntry(0, 0, 0, 0);

		public LineNumberEntry(int file, int row, int column, int offset)
			: this(file, row, column, offset, is_hidden: false)
		{
		}

		public LineNumberEntry(int file, int row, int offset)
			: this(file, row, -1, offset, is_hidden: false)
		{
		}

		public LineNumberEntry(int file, int row, int column, int offset, bool is_hidden)
			: this(file, row, column, -1, -1, offset, is_hidden)
		{
		}

		public LineNumberEntry(int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden)
		{
			File = file;
			Row = row;
			Column = column;
			EndRow = end_row;
			EndColumn = end_column;
			Offset = offset;
			IsHidden = is_hidden;
		}

		public override string ToString()
		{
			return $"[Line {File}:{Row},{Column}-{EndRow},{EndColumn}:{Offset}]";
		}
	}
	public class CodeBlockEntry
	{
		public enum Type
		{
			Lexical = 1,
			CompilerGenerated,
			IteratorBody,
			IteratorDispatcher
		}

		public int Index;

		public int Parent;

		public Type BlockType;

		public int StartOffset;

		public int EndOffset;

		public CodeBlockEntry(int index, int parent, Type type, int start_offset)
		{
			Index = index;
			Parent = parent;
			BlockType = type;
			StartOffset = start_offset;
		}

		internal CodeBlockEntry(int index, MyBinaryReader reader)
		{
			Index = index;
			int num = reader.ReadLeb128();
			BlockType = (Type)(num & 0x3F);
			Parent = reader.ReadLeb128();
			StartOffset = reader.ReadLeb128();
			EndOffset = reader.ReadLeb128();
			if (((uint)num & 0x40u) != 0)
			{
				int num2 = reader.ReadInt16();
				reader.BaseStream.Position += num2;
			}
		}

		public void Close(int end_offset)
		{
			EndOffset = end_offset;
		}

		internal void Write(MyBinaryWriter bw)
		{
			bw.WriteLeb128((int)BlockType);
			bw.WriteLeb128(Parent);
			bw.WriteLeb128(StartOffset);
			bw.WriteLeb128(EndOffset);
		}

		public override string ToString()
		{
			return $"[CodeBlock {Index}:{Parent}:{BlockType}:{StartOffset}:{EndOffset}]";
		}
	}
	public struct LocalVariableEntry
	{
		public readonly int Index;

		public readonly string Name;

		public readonly int BlockIndex;

		public LocalVariableEntry(int index, string name, int block)
		{
			Index = index;
			Name = name;
			BlockIndex = block;
		}

		internal LocalVariableEntry(MonoSymbolFile file, MyBinaryReader reader)
		{
			Index = reader.ReadLeb128();
			Name = reader.ReadString();
			BlockIndex = reader.ReadLeb128();
		}

		internal void Write(MonoSymbolFile file, MyBinaryWriter bw)
		{
			bw.WriteLeb128(Index);
			bw.Write(Name);
			bw.WriteLeb128(BlockIndex);
		}

		public override string ToString()
		{
			return $"[LocalVariable {Name}:{Index}:{BlockIndex - 1}]";
		}
	}
	public struct CapturedVariable
	{
		public enum CapturedKind : byte
		{
			Local,
			Parameter,
			This
		}

		public readonly string Name;

		public readonly string CapturedName;

		public readonly CapturedKind Kind;

		public CapturedVariable(string name, string captured_name, CapturedKind kind)
		{
			Name = name;
			CapturedName = captured_name;
			Kind = kind;
		}

		internal CapturedVariable(MyBinaryReader reader)
		{
			Name = reader.ReadString();
			CapturedName = reader.ReadString();
			Kind = (CapturedKind)reader.ReadByte();
		}

		internal void Write(MyBinaryWriter bw)
		{
			bw.Write(Name);
			bw.Write(CapturedName);
			bw.Write((byte)Kind);
		}

		public override string ToString()
		{
			return $"[CapturedVariable {Name}:{CapturedName}:{Kind}]";
		}
	}
	public struct CapturedScope
	{
		public readonly int Scope;

		public readonly string CapturedName;

		public CapturedScope(int scope, string captured_name)
		{
			Scope = scope;
			CapturedName = captured_name;
		}

		internal CapturedScope(MyBinaryReader reader)
		{
			Scope = reader.ReadLeb128();
			CapturedName = reader.ReadString();
		}

		internal void Write(MyBinaryWriter bw)
		{
			bw.WriteLeb128(Scope);
			bw.Write(CapturedName);
		}

		public override string ToString()
		{
			return $"[CapturedScope {Scope}:{CapturedName}]";
		}
	}
	public struct ScopeVariable
	{
		public readonly int Scope;

		public readonly int Index;

		public ScopeVariable(int scope, int index)
		{
			Scope = scope;
			Index = index;
		}

		internal ScopeVariable(MyBinaryReader reader)
		{
			Scope = reader.ReadLeb128();
			Index = reader.ReadLeb128();
		}

		internal void Write(MyBinaryWriter bw)
		{
			bw.WriteLeb128(Scope);
			bw.WriteLeb128(Index);
		}

		public override string ToString()
		{
			return $"[ScopeVariable {Scope}:{Index}]";
		}
	}
	public class AnonymousScopeEntry
	{
		public readonly int ID;

		private List<CapturedVariable> captured_vars = new List<CapturedVariable>();

		private List<CapturedScope> captured_scopes = new List<CapturedScope>();

		public CapturedVariable[] CapturedVariables
		{
			get
			{
				CapturedVariable[] array = new CapturedVariable[captured_vars.Count];
				captured_vars.CopyTo(array, 0);
				return array;
			}
		}

		public CapturedScope[] CapturedScopes
		{
			get
			{
				CapturedScope[] array = new CapturedScope[captured_scopes.Count];
				captured_scopes.CopyTo(array, 0);
				return array;
			}
		}

		public AnonymousScopeEntry(int id)
		{
			ID = id;
		}

		internal AnonymousScopeEntry(MyBinaryReader reader)
		{
			ID = reader.ReadLeb128();
			int num = reader.ReadLeb128();
			for (int i = 0; i < num; i++)
			{
				captured_vars.Add(new CapturedVariable(reader));
			}
			int num2 = reader.ReadLeb128();
			for (int j = 0; j < num2; j++)
			{
				captured_scopes.Add(new CapturedScope(reader));
			}
		}

		internal void AddCapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind)
		{
			captured_vars.Add(new CapturedVariable(name, captured_name, kind));
		}

		internal void AddCapturedScope(int scope, string captured_name)
		{
			captured_scopes.Add(new CapturedScope(scope, captured_name));
		}

		internal void Write(MyBinaryWriter bw)
		{
			bw.WriteLeb128(ID);
			bw.WriteLeb128(captured_vars.Count);
			foreach (CapturedVariable captured_var in captured_vars)
			{
				captured_var.Write(bw);
			}
			bw.WriteLeb128(captured_scopes.Count);
			foreach (CapturedScope captured_scope in captured_scopes)
			{
				captured_scope.Write(bw);
			}
		}

		public override string ToString()
		{
			return $"[AnonymousScope {ID}]";
		}
	}
	public class CompileUnitEntry : ICompileUnit
	{
		public readonly int Index;

		private int DataOffset;

		private MonoSymbolFile file;

		private SourceFileEntry source;

		private List<SourceFileEntry> include_files;

		private List<NamespaceEntry> namespaces;

		private bool creating;

		public static int Size => 8;

		CompileUnitEntry ICompileUnit.Entry => this;

		public SourceFileEntry SourceFile
		{
			get
			{
				if (creating)
				{
					return source;
				}
				ReadData();
				return source;
			}
		}

		public NamespaceEntry[] Namespaces
		{
			get
			{
				ReadData();
				NamespaceEntry[] array = new NamespaceEntry[namespaces.Count];
				namespaces.CopyTo(array, 0);
				return array;
			}
		}

		public SourceFileEntry[] IncludeFiles
		{
			get
			{
				ReadData();
				if (include_files == null)
				{
					return new SourceFileEntry[0];
				}
				SourceFileEntry[] array = new SourceFileEntry[include_files.Count];
				include_files.CopyTo(array, 0);
				return array;
			}
		}

		public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source)
		{
			this.file = file;
			this.source = source;
			Index = file.AddCompileUnit(this);
			creating = true;
			namespaces = new List<NamespaceEntry>();
		}

		public void AddFile(SourceFileEntry file)
		{
			if (!creating)
			{
				throw new InvalidOperationException();
			}
			if (include_files == null)
			{
				include_files = new List<SourceFileEntry>();
			}
			include_files.Add(file);
		}

		public int DefineNamespace(string name, string[] using_clauses, int parent)
		{
			if (!creating)
			{
				throw new InvalidOperationException();
			}
			int nextNamespaceIndex = file.GetNextNamespaceIndex();
			NamespaceEntry item = new NamespaceEntry(name, nextNamespaceIndex, using_clauses, parent);
			namespaces.Add(item);
			return nextNamespaceIndex;
		}

		internal void WriteData(MyBinaryWriter bw)
		{
			DataOffset = (int)bw.BaseStream.Position;
			bw.WriteLeb128(source.Index);
			int value = ((include_files != null) ? include_files.Count : 0);
			bw.WriteLeb128(value);
			if (include_files != null)
			{
				foreach (SourceFileEntry include_file in include_files)
				{
					bw.WriteLeb128(include_file.Index);
				}
			}
			bw.WriteLeb128(namespaces.Count);
			foreach (NamespaceEntry @namespace in namespaces)
			{
				@namespace.Write(file, bw);
			}
		}

		internal void Write(BinaryWriter bw)
		{
			bw.Write(Index);
			bw.Write(DataOffset);
		}

		internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader)
		{
			this.file = file;
			Index = reader.ReadInt32();
			DataOffset = reader.ReadInt32();
		}

		public void ReadAll()
		{
			ReadData();
		}

		private void ReadData()
		{
			if (creating)
			{
				throw new InvalidOperationException();
			}
			lock (file)
			{
				if (namespaces != null)
				{
					return;
				}
				MyBinaryReader binaryReader = file.BinaryReader;
				int num = (int)binaryReader.BaseStream.Position;
				binaryReader.BaseStream.Position = DataOffset;
				int index = binaryReader.ReadLeb128();
				source = file.GetSourceFile(index);
				int num2 = binaryReader.ReadLeb128();
				if (num2 > 0)
				{
					include_files = new List<SourceFileEntry>();
					for (int i = 0; i < num2; i++)
					{
						include_files.Add(file.GetSourceFile(binaryReader.ReadLeb128()));
					}
				}
				int num3 = binaryReader.ReadLeb128();
				namespaces = new List<NamespaceEntry>();
				for (int j = 0; j < num3; j++)
				{
					namespaces.Add(new NamespaceEntry(file, binaryReader));
				}
				binaryReader.BaseStream.Position = num;
			}
		}
	}
	public class SourceFileEntry
	{
		public readonly int Index;

		private int DataOffset;

		private MonoSymbolFile file;

		private string file_name;

		private byte[] guid;

		private byte[] hash;

		private bool creating;

		private bool auto_generated;

		private readonly string sourceFile;

		public static int Size => 8;

		public byte[] Checksum => hash;

		public string FileName
		{
			get
			{
				return file_name;
			}
			set
			{
				file_name = value;
			}
		}

		public bool AutoGenerated => auto_generated;

		public SourceFileEntry(MonoSymbolFile file, string file_name)
		{
			this.file = file;
			this.file_name = file_name;
			Index = file.AddSource(this);
			creating = true;
		}

		public SourceFileEntry(MonoSymbolFile file, string sourceFile, byte[] guid, byte[] checksum)
			: this(file, sourceFile, sourceFile, guid, checksum)
		{
		}

		public SourceFileEntry(MonoSymbolFile file, string fileName, string sourceFile, byte[] guid, byte[] checksum)
			: this(file, fileName)
		{
			this.guid = guid;
			hash = checksum;
			this.sourceFile = sourceFile;
		}

		internal void WriteData(MyBinaryWriter bw)
		{
			DataOffset = (int)bw.BaseStream.Position;
			bw.Write(file_name);
			if (guid == null)
			{
				guid = new byte[16];
			}
			if (hash == null)
			{
				try
				{
					using FileStream inputStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read);
					MD5 mD = MD5.Create();
					hash = mD.ComputeHash(inputStream);
				}
				catch
				{
					hash = new byte[16];
				}
			}
			bw.Write(guid);
			bw.Write(hash);
			bw.Write((byte)(auto_generated ? 1u : 0u));
		}

		internal void Write(BinaryWriter bw)
		{
			bw.Write(Index);
			bw.Write(DataOffset);
		}

		internal SourceFileEntry(MonoSymbolFile file, MyBinaryReader reader)
		{
			this.file = file;
			Index = reader.ReadInt32();
			DataOffset = reader.ReadInt32();
			int num = (int)reader.BaseStream.Position;
			reader.BaseStream.Position = DataOffset;
			sourceFile = (file_name = reader.ReadString());
			guid = reader.ReadBytes(16);
			hash = reader.ReadBytes(16);
			auto_generated = reader.ReadByte() == 1;
			reader.BaseStream.Position = num;
		}

		public void SetAutoGenerated()
		{
			if (!creating)
			{
				throw new InvalidOperationException();
			}
			auto_generated = true;
			file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource;
		}

		public bool CheckChecksum()
		{
			try
			{
				using FileStream inputStream = new FileStream(sourceFile, FileMode.Open);
				byte[] array = MD5.Create().ComputeHash(inputStream);
				for (int i = 0; i < 16; i++)
				{
					if (array[i] != hash[i])
					{
						return false;
					}
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		public override string ToString()
		{
			return $"SourceFileEntry ({Index}:{DataOffset})";
		}
	}
	public class LineNumberTable
	{
		protected LineNumberEntry[] _line_numbers;

		public readonly int LineBase;

		public readonly int LineRange;

		public readonly byte OpcodeBase;

		public readonly int MaxAddressIncrement;

		public const int Default_LineBase = -1;

		public const int Default_LineRange = 8;

		public const byte Default_OpcodeBase = 9;

		public const byte DW_LNS_copy = 1;

		public const byte DW_LNS_advance_pc = 2;

		public const byte DW_LNS_advance_line = 3;

		public const byte DW_LNS_set_file = 4;

		public const byte DW_LNS_const_add_pc = 8;

		public const byte DW_LNE_end_sequence = 1;

		public const byte DW_LNE_MONO_negate_is_hidden = 64;

		internal const byte DW_LNE_MONO__extensions_start = 64;

		internal const byte DW_LNE_MONO__extensions_end = 127;

		public LineNumberEntry[] LineNumbers => _line_numbers;

		protected LineNumberTable(MonoSymbolFile file)
		{
			LineBase = file.OffsetTable.LineNumberTable_LineBase;
			LineRange = file.OffsetTable.LineNumberTable_LineRange;
			OpcodeBase = (byte)file.OffsetTable.LineNumberTable_OpcodeBase;
			MaxAddressIncrement = (255 - OpcodeBase) / LineRange;
		}

		internal LineNumberTable(MonoSymbolFile file, LineNumberEntry[] lines)
			: this(file)
		{
			_line_numbers = lines;
		}

		internal void Write(MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo)
		{
			int num = (int)bw.BaseStream.Position;
			bool flag = false;
			int num2 = 1;
			int num3 = 0;
			int num4 = 1;
			for (int i = 0; i < LineNumbers.Length; i++)
			{
				int num5 = LineNumbers[i].Row - num2;
				int num6 = LineNumbers[i].Offset - num3;
				if (LineNumbers[i].File != num4)
				{
					bw.Write((byte)4);
					bw.WriteLeb128(LineNumbers[i].File);
					num4 = LineNumbers[i].File;
				}
				if (LineNumbers[i].IsHidden != flag)
				{
					bw.Write((byte)0);
					bw.Write((byte)1);
					bw.Write((byte)64);
					flag = LineNumbers[i].IsHidden;
				}
				if (num6 >= MaxAddressIncrement)
				{
					if (num6 < 2 * MaxAddressIncrement)
					{
						bw.Write((byte)8);
						num6 -= MaxAddressIncrement;
					}
					else
					{
						bw.Write((byte)2);
						bw.WriteLeb128(num6);
						num6 = 0;
					}
				}
				if (num5 < LineBase || num5 >= LineBase + LineRange)
				{
					bw.Write((byte)3);
					bw.WriteLeb128(num5);
					if (num6 != 0)
					{
						bw.Write((byte)2);
						bw.WriteLeb128(num6);
					}
					bw.Write((byte)1);
				}
				else
				{
					byte value = (byte)(num5 - LineBase + LineRange * num6 + OpcodeBase);
					bw.Write(value);
				}
				num2 = LineNumbers[i].Row;
				num3 = LineNumbers[i].Offset;
			}
			bw.Write((byte)0);
			bw.Write((byte)1);
			bw.Write((byte)1);
			if (hasColumnsInfo)
			{
				for (int j = 0; j < LineNumbers.Length; j++)
				{
					LineNumberEntry lineNumberEntry = LineNumbers[j];
					if (lineNumberEntry.Row >= 0)
					{
						bw.WriteLeb128(lineNumberEntry.Column);
					}
				}
			}
			if (hasEndInfo)
			{
				for (int k = 0; k < LineNumbers.Length; k++)
				{
					LineNumberEntry lineNumberEntry2 = LineNumbers[k];
					if (lineNumberEntry2.EndRow == -1 || lineNumberEntry2.EndColumn == -1 || lineNumberEntry2.Row > lineNumberEntry2.EndRow)
					{
						bw.WriteLeb128(16777215);
						continue;
					}
					bw.WriteLeb128(lineNumberEntry2.EndRow - lineNumberEntry2.Row);
					bw.WriteLeb128(lineNumberEntry2.EndColumn);
				}
			}
			file.ExtendedLineNumberSize += (int)bw.BaseStream.Position - num;
		}

		internal static LineNumberTable Read(MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo)
		{
			LineNumberTable lineNumberTable = new LineNumberTable(file);
			lineNumberTable.DoRead(file, br, readColumnsInfo, readEndInfo);
			return lineNumberTable;
		}

		private void DoRead(MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds)
		{
			List<LineNumberEntry> list = new List<LineNumberEntry>();
			bool flag = false;
			bool flag2 = false;
			int num = 1;
			int num2 = 0;
			int file2 = 1;
			while (true)
			{
				byte b = br.ReadByte();
				if (b == 0)
				{
					byte b2 = br.ReadByte();
					long position = br.BaseStream.Position + b2;
					b = br.ReadByte();
					switch (b)
					{
					case 1:
					{
						if (flag2)
						{
							list.Add(new LineNumberEntry(file2, num, -1, num2, flag));
						}
						_line_numbers = list.ToArray();
						if (includesColumns)
						{
							for (int i = 0; i < _line_numbers.Length; i++)
							{
								LineNumberEntry lineNumberEntry = _line_numbers[i];
								if (lineNumberEntry.Row >= 0)
								{
									lineNumberEntry.Column = br.ReadLeb128();
								}
							}
						}
						if (!includesEnds)
						{
							return;
						}
						for (int j = 0; j < _line_numbers.Length; j++)
						{
							LineNumberEntry lineNumberEntry2 = _line_numbers[j];
							int num3 = br.ReadLeb128();
							if (num3 == 16777215)
							{
								lineNumberEntry2.EndRow = -1;
								lineNumberEntry2.EndColumn = -1;
							}
							else
							{
								lineNumberEntry2.EndRow = lineNumberEntry2.Row + num3;
								lineNumberEntry2.EndColumn = br.ReadLeb128();
							}
						}
						return;
					}
					case 64:
						flag = !flag;
						flag2 = true;
						break;
					default:
						throw new MonoSymbolFileException("Unknown extended opcode {0:x}", b);
					case 65:
					case 66:
					case 67:
					case 68:
					case 69:
					case 70:
					case 71:
					case 72:
					case 73:
					case 74:
					case 75:
					case 76:
					case 77:
					case 78:
					case 79:
					case 80:
					case 81:
					case 82:
					case 83:
					case 84:
					case 85:
					case 86:
					case 87:
					case 88:
					case 89:
					case 90:
					case 91:
					case 92:
					case 93:
					case 94:
					case 95:
					case 96:
					case 97:
					case 98:
					case 99:
					case 100:
					case 101:
					case 102:
					case 103:
					case 104:
					case 105:
					case 106:
					case 107:
					case 108:
					case 109:
					case 110:
					case 111:
					case 112:
					case 113:
					case 114:
					case 115:
					case 116:
					case 117:
					case 118:
					case 119:
					case 120:
					case 121:
					case 122:
					case 123:
					case 124:
					case 125:
					case 126:
					case 127:
						break;
					}
					br.BaseStream.Position = position;
				}
				else if (b < OpcodeBase)
				{
					switch (b)
					{
					case 1:
						list.Add(new LineNumberEntry(file2, num, -1, num2, flag));
						flag2 = false;
						break;
					case 2:
						num2 += br.ReadLeb128();
						flag2 = true;
						break;
					case 3:
						num += br.ReadLeb128();
						flag2 = true;
						break;
					case 4:
						file2 = br.ReadLeb128();
						flag2 = true;
						break;
					case 8:
						num2 += MaxAddressIncrement;
						flag2 = true;
						break;
					default:
						throw new MonoSymbolFileException("Unknown standard opcode {0:x} in LNT", b);
					}
				}
				else
				{
					b -= OpcodeBase;
					num2 += b / LineRange;
					num += LineBase + b % LineRange;
					list.Add(new LineNumberEntry(file2, num, -1, num2, flag));
					flag2 = false;
				}
			}
		}

		public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end)
		{
			if (_line_numbers.Length > 1)
			{
				start = _line_numbers[0];
				end = _line_numbers[_line_numbers.Length - 1];
				return true;
			}
			start = LineNumberEntry.Null;
			end = LineNumberEntry.Null;
			return false;
		}
	}
	public class MethodEntry : IComparable
	{
		[Flags]
		public enum Flags
		{
			LocalNamesAmbiguous = 1,
			ColumnsInfoIncluded = 2,
			EndInfoIncluded = 4
		}

		public readonly int CompileUnitIndex;

		public readonly int Token;

		public readonly int NamespaceID;

		private int DataOffset;

		private int LocalVariableTableOffset;

		private int LineNumberTableOffset;

		private int CodeBlockTableOffset;

		private int ScopeVariableTableOffset;

		private int RealNameOffset;

		private Flags flags;

		private int index;

		public readonly CompileUnitEntry CompileUnit;

		private LocalVariableEntry[] locals;

		private CodeBlockEntry[] code_blocks;

		private ScopeVariable[] scope_vars;

		private LineNumberTable lnt;

		private string real_name;

		public readonly MonoSymbolFile SymbolFile;

		public const int Size = 12;

		public Flags MethodFlags => flags;

		public int Index
		{
			get
			{
				return index;
			}
			set
			{
				index = value;
			}
		}

		internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index)
		{
			SymbolFile = file;
			this.index = index;
			Token = reader.ReadInt32();
			DataOffset = reader.ReadInt32();
			LineNumberTableOffset = reader.ReadInt32();
			long position = reader.BaseStream.Position;
			reader.BaseStream.Position = DataOffset;
			CompileUnitIndex = reader.ReadLeb128();
			LocalVariableTableOffset = reader.ReadLeb128();
			NamespaceID = reader.ReadLeb128();
			CodeBlockTableOffset = reader.ReadLeb128();
			ScopeVariableTableOffset = reader.ReadLeb128();
			RealNameOffset = reader.ReadLeb128();
			flags = (Flags)reader.ReadLeb128();
			reader.BaseStream.Position = position;
			CompileUnit = file.GetCompileUnit(CompileUnitIndex);
		}

		internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, Flags flags, int namespace_id)
		{
			SymbolFile = file;
			this.real_name = real_name;
			this.locals = locals;
			this.code_blocks = code_blocks;
			this.scope_vars = scope_vars;
			this.flags = flags;
			index = -1;
			Token = token;
			CompileUnitIndex = comp_unit.Index;
			CompileUnit = comp_unit;
			NamespaceID = namespace_id;
			CheckLineNumberTable(lines);
			lnt = new LineNumberTable(file, lines);
			file.NumLineNumbers += lines.Length;
			int num = ((locals != null) ? locals.Length : 0);
			if (num <= 32)
			{
				for (int i = 0; i < num; i++)
				{
					string name = locals[i].Name;
					for (int j = i + 1; j < num; j++)
					{
						if (locals[j].Name == name)
						{
							flags |= Flags.LocalNamesAmbiguous;
							return;
						}
					}
				}
				return;
			}
			Dictionary<string, LocalVariableEntry> dictionary = new Dictionary<string, LocalVariableEntry>();
			for (int k = 0; k < locals.Length; k++)
			{
				LocalVariableEntry value = locals[k];
				if (dictionary.ContainsKey(value.Name))
				{
					flags |= Flags.LocalNamesAmbiguous;
					break;
				}
				dictionary.Add(value.Name, value);
			}
		}

		private static void CheckLineNumberTable(LineNumberEntry[] line_numbers)
		{
			int num = -1;
			int num2 = -1;
			if (line_numbers == null)
			{
				return;
			}
			foreach (LineNumberEntry lineNumberEntry in line_numbers)
			{
				if (lineNumberEntry.Equals(LineNumberEntry.Null))
				{
					throw new MonoSymbolFileException();
				}
				if (lineNumberEntry.Offset < num)
				{
					throw new MonoSymbolFileException();
				}
				if (lineNumberEntry.Offset > num)
				{
					num2 = lineNumberEntry.Row;
					num = lineNumberEntry.Offset;
				}
				else if (lineNumberEntry.Row > num2)
				{
					num2 = lineNumberEntry.Row;
				}
			}
		}

		internal void Write(MyBinaryWriter bw)
		{
			if (index <= 0 || DataOffset == 0)
			{
				throw new InvalidOperationException();
			}
			bw.Write(Token);
			bw.Write(DataOffset);
			bw.Write(LineNumberTableOffset);
		}

		internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw)
		{
			if (index <= 0)
			{
				throw new InvalidOperationException();
			}
			LocalVariableTableOffset = (int)bw.BaseStream.Position;
			int num = ((locals != null) ? locals.Length : 0);
			bw.WriteLeb128(num);
			for (int i = 0; i < num; i++)
			{
				locals[i].Write(file, bw);
			}
			file.LocalCount += num;
			CodeBlockTableOffset = (int)bw.BaseStream.Position;
			int num2 = ((code_blocks != null) ? code_blocks.Length : 0);
			bw.WriteLeb128(num2);
			for (int j = 0; j < num2; j++)
			{
				code_blocks[j].Write(bw);
			}
			ScopeVariableTableOffset = (int)bw.BaseStream.Position;
			int num3 = ((scope_vars != null) ? scope_vars.Length : 0);
			bw.WriteLeb128(num3);
			for (int k = 0; k < num3; k++)
			{
				scope_vars[k].Write(bw);
			}
			if (real_name != null)
			{
				RealNameOffset = (int)bw.BaseStream.Position;
				bw.Write(real_name);
			}
			LineNumberEntry[] lineNumbers = lnt.LineNumbers;
			foreach (LineNumberEntry lineNumberEntry in lineNumbers)
			{
				if (lineNumberEntry.EndRow != -1 || lineNumberEntry.EndColumn != -1)
				{
					flags |= Flags.EndInfoIncluded;
				}
			}
			LineNumberTableOffset = (int)bw.BaseStream.Position;
			lnt.Write(file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0);
			DataOffset = (int)bw.BaseStream.Position;
			bw.WriteLeb128(CompileUnitIndex);
			bw.WriteLeb128(LocalVariableTableOffset);
			bw.WriteLeb128(NamespaceID);
			bw.WriteLeb128(CodeBlockTableOffset);
			bw.WriteLeb128(ScopeVariableTableOffset);
			bw.WriteLeb128(RealNameOffset);
			bw.WriteLeb128((int)flags);
		}

		public void ReadAll()
		{
			GetLineNumberTable();
			GetLocals();
			GetCodeBlocks();
			GetScopeVariables();
			GetRealName();
		}

		public LineNumberTable GetLineNumberTable()
		{
			lock (SymbolFile)
			{
				if (lnt != null)
				{
					return lnt;
				}
				if (LineNumberTableOffset == 0)
				{
					return null;
				}
				MyBinaryReader binaryReader = SymbolFile.BinaryReader;
				long position = binaryReader.BaseStream.Position;
				binaryReader.BaseStream.Position = LineNumberTableOffset;
				lnt = LineNumberTable.Read(SymbolFile, binaryReader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0);
				binaryReader.BaseStream.Position = position;
				return lnt;
			}
		}

		public LocalVariableEntry[] GetLocals()
		{
			lock (SymbolFile)
			{
				if (locals != null)
				{
					return locals;
				}
				if (LocalVariableTableOffset == 0)
				{
					return null;
				}
				MyBinaryReader binaryReader = SymbolFile.BinaryReader;
				long position = binaryReader.BaseStream.Position;
				binaryReader.BaseStream.Position = LocalVariableTableOffset;
				int num = binaryReader.ReadLeb128();
				locals = new LocalVariableEntry[num];
				for (int i = 0; i < num; i++)
				{
					locals[i] = new LocalVariableEntry(SymbolFile, binaryReader);
				}
				binaryReader.BaseStream.Position = position;
				return locals;
			}
		}

		public CodeBlockEntry[] GetCodeBlocks()
		{
			lock (SymbolFile)
			{
				if (code_blocks != null)
				{
					return code_blocks;
				}
				if (CodeBlockTableOffset == 0)
				{
					return null;
				}
				MyBinaryReader binaryReader = SymbolFile.BinaryReader;
				long position = binaryReader.BaseStream.Position;
				binaryReader.BaseStream.Position = CodeBlockTableOffset;
				int num = binaryReader.ReadLeb128();
				code_blocks = new CodeBlockEntry[num];
				for (int i = 0; i < num; i++)
				{
					code_blocks[i] = new CodeBlockEntry(i, binaryReader);
				}
				binaryReader.BaseStream.Position = position;
				return code_blocks;
			}
		}

		public ScopeVariable[] GetScopeVariables()
		{
			lock (SymbolFile)
			{
				if (scope_vars != null)
				{
					return scope_vars;
				}
				if (ScopeVariableTableOffset == 0)
				{
					return null;
				}
				MyBinaryReader binaryReader = SymbolFile.BinaryReader;
				long position = binaryReader.BaseStream.Position;
				binaryReader.BaseStream.Position = ScopeVariableTableOffset;
				int num = binaryReader.ReadLeb128();
				scope_vars = new ScopeVariable[num];
				for (int i = 0; i < num; i++)
				{
					scope_vars[i] = new ScopeVariable(binaryReader);
				}
				binaryReader.BaseStream.Position = position;
				return scope_vars;
			}
		}

		public string GetRealName()
		{
			lock (SymbolFile)
			{
				if (real_name != null)
				{
					return real_name;
				}
				if (RealNameOffset == 0)
				{
					return null;
				}
				real_name = SymbolFile.BinaryReader.ReadString(RealNameOffset);
				return real_name;
			}
		}

		public int CompareTo(object obj)
		{
			MethodEntry methodEntry = (MethodEntry)obj;
			if (methodEntry.Token < Token)
			{
				return 1;
			}
			if (methodEntry.Token > Token)
			{
				return -1;
			}
			return 0;
		}

		public override string ToString()
		{
			return $"[Method {index}:{Token:x}:{CompileUnitIndex}:{CompileUnit}]";
		}
	}
	public struct NamespaceEntry
	{
		public readonly string Name;

		public readonly int Index;

		public readonly int Parent;

		public readonly string[] UsingClauses;

		public NamespaceEntry(string name, int index, string[] using_clauses, int parent)
		{
			Name = name;
			Index = index;
			Parent = parent;
			UsingClauses = ((using_clauses != null) ? using_clauses : new string[0]);
		}

		internal NamespaceEntry(MonoSymbolFile file, MyBinaryReader reader)
		{
			Name = reader.ReadString();
			Index = reader.ReadLeb128();
			Parent = reader.ReadLeb128();
			int num = reader.ReadLeb128();
			UsingClauses = new string[num];
			for (int i = 0; i < num; i++)
			{
				UsingClauses[i] = reader.ReadString();
			}
		}

		internal void Write(MonoSymbolFile file, MyBinaryWriter bw)
		{
			bw.Write(Name);
			bw.WriteLeb128(Index);
			bw.WriteLeb128(Parent);
			bw.WriteLeb128(UsingClauses.Length);
			string[] usingClauses = UsingClauses;
			foreach (string value in usingClauses)
			{
				bw.Write(value);
			}
		}

		public override string ToString()
		{
			return $"[Namespace {Name}:{Index}:{Parent}]";
		}
	}
	public class MonoSymbolWriter
	{
		private List<SourceMethodBuilder> methods;

		private List<SourceFileEntry> sources;

		private List<CompileUnitEntry> comp_units;

		protected readonly MonoSymbolFile file;

		private string filename;

		private SourceMethodBuilder current_method;

		private Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder>();

		public MonoSymbolFile SymbolFile => file;

		public MonoSymbolWriter(string filename)
		{
			methods = new List<SourceMethodBuilder>();
			sources = new List<SourceFileEntry>();
			comp_units = new List<CompileUnitEntry>();
			file = new MonoSymbolFile();
			this.filename = filename + ".mdb";
		}

		public void CloseNamespace()
		{
		}

		public void DefineLocalVariable(int index, string name)
		{
			if (current_method != null)
			{
				current_method.AddLocal(index, name);
			}
		}

		public void DefineCapturedLocal(int scope_id, string name, string captured_name)
		{
			file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Local);
		}

		public void DefineCapturedParameter(int scope_id, string name, string captured_name)
		{
			file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Parameter);
		}

		public void DefineCapturedThis(int scope_id, string captured_name)
		{
			file.DefineCapturedVariable(scope_id, "this", captured_name, CapturedVariable.CapturedKind.This);
		}

		public void DefineCapturedScope(int scope_id, int id, string captured_name)
		{
			file.DefineCapturedScope(scope_id, id, captured_name);
		}

		public void DefineScopeVariable(int scope, int index)
		{
			if (current_method != null)
			{
				current_method.AddScopeVariable(scope, index);
			}
		}

		public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden)
		{
			if (current_method != null)
			{
				current_method.MarkSequencePoint(offset, file, line, column, is_hidden);
			}
		}

		public SourceMethodBuilder OpenMethod(ICompileUnit file, int ns_id, IMethodDef method)
		{
			SourceMethodBuilder result = new SourceMethodBuilder(file, ns_id, method);
			current_method_stack.Push(current_method);
			current_method = result;
			methods.Add(current_method);
			return result;
		}

		public void CloseMethod()
		{
			current_method = current_method_stack.Pop();
		}

		public SourceFileEntry DefineDocument(string url)
		{
			SourceFileEntry sourceFileEntry = new SourceFileEntry(file, url);
			sources.Add(sourceFileEntry);
			return sourceFileEntry;
		}

		public SourceFileEntry DefineDocument(string url, byte[] guid, byte[] checksum)
		{
			SourceFileEntry sourceFileEntry = new SourceFileEntry(file, url, guid, checksum);
			sources.Add(sourceFileEntry);
			return sourceFileEntry;
		}

		public CompileUnitEntry DefineCompilationUnit(SourceFileEntry source)
		{
			CompileUnitEntry compileUnitEntry = new CompileUnitEntry(file, source);
			comp_units.Add(compileUnitEntry);
			return compileUnitEntry;
		}

		public int DefineNamespace(string name, CompileUnitEntry unit, string[] using_clauses, int parent)
		{
			if (unit == null || using_clauses == null)
			{
				throw new NullReferenceException();
			}
			return unit.DefineNamespace(name, using_clauses, parent);
		}

		public int OpenScope(int start_offset)
		{
			if (current_method == null)
			{
				return 0;
			}
			current_method.StartBlock(CodeBlockEntry.Type.Lexical, start_offset);
			return 0;
		}

		public void CloseScope(int end_offset)
		{
			if (current_method != null)
			{
				current_method.EndBlock(end_offset);
			}
		}

		public void OpenCompilerGeneratedBlock(int start_offset)
		{
			if (current_method != null)
			{
				current_method.StartBlock(CodeBlockEntry.Type.CompilerGenerated, start_offset);
			}
		}

		public void CloseCompilerGeneratedBlock(int end_offset)
		{
			if (current_method != null)
			{
				current_method.EndBlock(end_offset);
			}
		}

		public void StartIteratorBody(int start_offset)
		{
			current_method.StartBlock(CodeBlockEntry.Type.IteratorBody, start_offset);
		}

		public void EndIteratorBody(int end_offset)
		{
			current_method.EndBlock(end_offset);
		}

		public void StartIteratorDispatcher(int start_offset)
		{
			current_method.StartBlock(CodeBlockEntry.Type.IteratorDispatcher, start_offset);
		}

		public void EndIteratorDispatcher(int end_offset)
		{
			current_method.EndBlock(end_offset);
		}

		public void DefineAnonymousScope(int id)
		{
			file.DefineAnonymousScope(id);
		}

		public void WriteSymbolFile(Guid guid)
		{
			foreach (SourceMethodBuilder method in methods)
			{
				method.DefineMethod(file);
			}
			try
			{
				File.Delete(filename);
			}
			catch
			{
			}
			using FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
			file.CreateSymbolFile(guid, fs);
		}
	}
	public class SourceMethodBuilder
	{
		private List<LocalVariableEntry> _locals;

		private List<CodeBlockEntry> _blocks;

		private List<ScopeVariable> _scope_vars;

		private Stack<CodeBlockEntry> _block_stack;

		private readonly List<LineNumberEntry> method_lines;

		private readonly ICompileUnit _comp_unit;

		private readonly int ns_id;

		private readonly IMethodDef method;

		public CodeBlockEntry[] Blocks
		{
			get
			{
				if (_blocks == null)
				{
					return new CodeBlockEntry[0];
				}
				CodeBlockEntry[] array = new CodeBlockEntry[_blocks.Count];
				_blocks.CopyTo(array, 0);
				return array;
			}
		}

		public CodeBlockEntry CurrentBlock
		{
			get
			{
				if (_block_stack != null && _block_stack.Count > 0)
				{
					return _block_stack.Peek();
				}
				return null;
			}
		}

		public LocalVariableEntry[] Locals
		{
			get
			{
				if (_locals == null)
				{
					return new LocalVariableEntry[0];
				}
				return _locals.ToArray();
			}
		}

		public ICompileUnit SourceFile => _comp_unit;

		public ScopeVariable[] ScopeVariables
		{
			get
			{
				if (_scope_vars == null)
				{
					return new ScopeVariable[0];
				}
				return _scope_vars.ToArray();
			}
		}

		public SourceMethodBuilder(ICompileUnit comp_unit)
		{
			_comp_unit = comp_unit;
			method_lines = new List<LineNumberEntry>();
		}

		public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method)
			: this(comp_unit)
		{
			this.ns_id = ns_id;
			this.method = method;
		}

		public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden)
		{
			MarkSequencePoint(offset, file, line, column, -1, -1, is_hidden);
		}

		public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden)
		{
			LineNumberEntry lineNumberEntry = new LineNumberEntry(file?.Index ?? 0, line, column, end_line, end_column, offset, is_hidden);
			if (method_lines.Count > 0)
			{
				LineNumberEntry lineNumberEntry2 = method_lines[method_lines.Count - 1];
				if (lineNumberEntry2.Offset == offset)
				{
					if (LineNumberEntry.LocationComparer.Default.Compare(lineNumberEntry, lineNumberEntry2) > 0)
					{
						method_lines[method_lines.Count - 1] = lineNumberEntry;
					}
					return;
				}
			}
			method_lines.Add(lineNumberEntry);
		}

		public void StartBlock(CodeBlockEntry.Type type, int start_offset)
		{
			StartBlock(type, start_offset, (_blocks == null) ? 1 : (_blocks.Count + 1));
		}

		public void StartBlock(CodeBlockEntry.Type type, int start_offset, int scopeIndex)
		{
			if (_block_stack == null)
			{
				_block_stack = new Stack<CodeBlockEntry>();
			}
			if (_blocks == null)
			{
				_blocks = new List<CodeBlockEntry>();
			}
			int parent = ((CurrentBlock != null) ? CurrentBlock.Index : (-1));
			CodeBlockEntry item = new CodeBlockEntry(scopeIndex, parent, type, start_offset);
			_block_stack.Push(item);
			_blocks.Add(item);
		}

		public void EndBlock(int end_offset)
		{
			_block_stack.Pop().Close(end_offset);
		}

		public void AddLocal(int index, string name)
		{
			if (_locals == null)
			{
				_locals = new List<LocalVariableEntry>();
			}
			int block = ((CurrentBlock != null) ? CurrentBlock.Index : 0);
			_locals.Add(new LocalVariableEntry(index, name, block));
		}

		public void AddScopeVariable(int scope, int index)
		{
			if (_scope_vars == null)
			{
				_scope_vars = new List<ScopeVariable>();
			}
			_scope_vars.Add(new ScopeVariable(scope, index));
		}

		public void DefineMethod(MonoSymbolFile file)
		{
			DefineMethod(file, method.Token);
		}

		public void DefineMethod(MonoSymbolFile file, int token)
		{
			CodeBlockEntry[] array = Blocks;
			if (array.Length != 0)
			{
				List<CodeBlockEntry> list = new List<CodeBlockEntry>(array.Length);
				int num = 0;
				for (int i = 0; i < array.Length; i++)
				{
					num = Math.Max(num, array[i].Index);
				}
				for (int j = 0; j < num; j++)
				{
					int num2 = j + 1;
					if (j < array.Length && array[j].Index == num2)
					{
						list.Add(array[j]);
						continue;
					}
					bool flag = false;
					for (int k = 0; k < array.Length; k++)
					{
						if (array[k].Index == num2)
						{
							list.Add(array[k]);
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						list.Add(new CodeBlockEntry(num2, -1, CodeBlockEntry.Type.CompilerGenerated, 0));
					}
				}
				array = list.ToArray();
			}
			MethodEntry entry = new MethodEntry(file, _comp_unit.Entry, token, ScopeVariables, Locals, method_lines.ToArray(), array, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
			file.AddMethod(entry);
		}
	}
	public class SymbolWriterImpl : ISymbolWriter
	{
		private MonoSymbolWriter msw;

		private int nextLocalIndex;

		private int currentToken;

		private string methodName;

		private Stack namespaceStack = new Stack();

		private bool methodOpened;

		private Hashtable documents = new Hashtable();

		private Guid guid;

		public SymbolWriterImpl(Guid guid)
		{
			this.guid = guid;
		}

		public void Close()
		{
			msw.WriteSymbolFile(guid);
		}

		public void CloseMethod()
		{
			if (methodOpened)
			{
				methodOpened = false;
				nextLocalIndex = 0;
				msw.CloseMethod();
			}
		}

		public void CloseNamespace()
		{
			namespaceStack.Pop();
			msw.CloseNamespace();
		}

		public void CloseScope(int endOffset)
		{
			msw.CloseScope(endOffset);
		}

		public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType)
		{
			SymbolDocumentWriterImpl symbolDocumentWriterImpl = (SymbolDocumentWriterImpl)documents[url];
			if (symbolDocumentWriterImpl == null)
			{
				SourceFileEntry source = msw.DefineDocument(url);
				symbolDocumentWriterImpl = new SymbolDocumentWriterImpl(msw.DefineCompilationUnit(source));
				documents[url] = symbolDocumentWriterImpl;
			}
			return symbolDocumentWriterImpl;
		}

		public void DefineField(SymbolToken parent, string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3)
		{
		}

		public void DefineGlobalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3)
		{
		}

		public void DefineLocalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset)
		{
			msw.DefineLocalVariable(nextLocalIndex++, name);
		}

		public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3)
		{
		}

		public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns)
		{
			SourceFileEntry file = ((SymbolDocumentWriterImpl)document)?.Entry.SourceFile;
			for (int i = 0; i < offsets.Length; i++)
			{
				if (i <= 0 || offsets[i] != offsets[i - 1] || lines[i] != lines[i - 1] || columns[i] != columns[i - 1])
				{
					msw.MarkSequencePoint(offsets[i], file, lines[i], columns[i], is_hidden: false);
				}
			}
		}

		public void Initialize(IntPtr emitter, string filename, bool fFullBuild)
		{
			msw = new MonoSymbolWriter(filename);
		}

		public void OpenMethod(SymbolToken method)
		{
			currentToken = method.GetToken();
		}

		public void OpenNamespace(string name)
		{
			NamespaceInfo namespaceInfo = new NamespaceInfo();
			namespaceInfo.NamespaceID = -1;
			namespaceInfo.Name = name;
			namespaceStack.Push(namespaceInfo);
		}

		public int OpenScope(int startOffset)
		{
			return msw.OpenScope(startOffset);
		}

		public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn)
		{
			int currentNamespace = GetCurrentNamespace(startDoc);
			SourceMethodImpl method = new SourceMethodImpl(methodName, currentToken, currentNamespace);
			msw.OpenMethod(((ICompileUnit)startDoc).Entry, currentNamespace, method);
			methodOpened = true;
		}

		public void SetScopeRange(int scopeID, int startOffset, int endOffset)
		{
		}

		public void SetSymAttribute(SymbolToken parent, string name, byte[] data)
		{
			if (name == "__name")
			{
				methodName = Encoding.UTF8.GetString(data);
			}
		}

		public void SetUnderlyingWriter(IntPtr underlyingWriter)
		{
		}

		public void SetUserEntryPoint(SymbolToken entryMethod)
		{
		}

		public void UsingNamespace(string fullName)
		{
			if (namespaceStack.Count == 0)
			{
				OpenNamespace("");
			}
			NamespaceInfo namespaceInfo = (NamespaceInfo)namespaceStack.Peek();
			if (namespaceInfo.NamespaceID != -1)
			{
				NamespaceInfo namespaceInfo2 = namespaceInfo;
				CloseNamespace();
				OpenNamespace(namespaceInfo2.Name);
				namespaceInfo = (NamespaceInfo)namespaceStack.Peek();
				namespaceInfo.UsingClauses = namespaceInfo2.UsingClauses;
			}
			namespaceInfo.UsingClauses.Add(fullName);
		}

		private int GetCurrentNamespace(ISymbolDocumentWriter doc)
		{
			if (namespaceStack.Count == 0)
			{
				OpenNamespace("");
			}
			NamespaceInfo namespaceInfo = (NamespaceInfo)namespaceStack.Peek();
			if (namespaceInfo.NamespaceID == -1)
			{
				string[] using_clauses = (string[])namespaceInfo.UsingClauses.ToArray(typeof(string));
				int parent = 0;
				if (namespaceStack.Count > 1)
				{
					namespaceStack.Pop();
					parent = ((NamespaceInfo)namespaceStack.Peek()).NamespaceID;
					namespaceStack.Push(namespaceInfo);
				}
				namespaceInfo.NamespaceID = msw.DefineNamespace(namespaceInfo.Name, ((ICompileUnit)doc).Entry, using_clauses, parent);
			}
			return namespaceInfo.NamespaceID;
		}
	}
	internal class SymbolDocumentWriterImpl : ISymbolDocumentWriter, ISourceFile, ICompileUnit
	{
		private CompileUnitEntry comp_unit;

		SourceFileEntry ISourceFile.Entry => comp_unit.SourceFile;

		public CompileUnitEntry Entry => comp_unit;

		public SymbolDocumentWriterImpl(CompileUnitEntry comp_unit)
		{
			this.comp_unit = comp_unit;
		}

		public void SetCheckSum(Guid algorithmId, byte[] checkSum)
		{
		}

		public void SetSource(byte[] source)
		{
		}
	}
	internal class SourceMethodImpl : IMethodDef
	{
		private string name;

		private int token;

		private int namespaceID;

		public string Name => name;

		public int NamespaceID => namespaceID;

		public int Token => token;

		public SourceMethodImpl(string name, int token, int namespaceID)
		{
			this.name = name;
			this.token = token;
			this.namespaceID = namespaceID;
		}
	}
	internal class NamespaceInfo
	{
		public string Name;

		public int NamespaceID;

		public ArrayList UsingClauses = new ArrayList();
	}
}
namespace Mono.Cecil.Mdb
{
	public sealed class MdbReaderProvider : ISymbolReaderProvider
	{
		public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
		{
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			return (ISymbolReader)(object)new MdbReader(module, MonoSymbolFile.ReadSymbolFile(Mixin.GetMdbFileName(fileName)));
		}

		public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream)
		{
			Mixin.CheckModule(module);
			Mixin.CheckStream((object)symbolStream);
			return (ISymbolReader)(object)new MdbReader(module, MonoSymbolFile.ReadSymbolFile(symbolStream));
		}
	}
	public sealed class MdbReader : ISymbolReader, IDisposable
	{
		private readonly ModuleDefinition module;

		private readonly MonoSymbolFile symbol_file;

		private readonly Dictionary<string, Document> documents;

		public MdbReader(ModuleDefinition module, MonoSymbolFile symFile)
		{
			this.module = module;
			symbol_file = symFile;
			documents = new Dictionary<string, Document>();
		}

		public ISymbolWriterProvider GetWriterProvider()
		{
			return (ISymbolWriterProvider)(object)new MdbWriterProvider();
		}

		public bool ProcessDebugHeader(ImageDebugHeader header)
		{
			return symbol_file.Guid == module.Mvid;
		}

		public MethodDebugInformation Read(MethodDefinition method)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			MetadataToken metadataToken = ((MemberReference)method).MetadataToken;
			MethodEntry methodByToken = symbol_file.GetMethodByToken(((MetadataToken)(ref metadataToken)).ToInt32());
			if (methodByToken == null)
			{
				return null;
			}
			MethodDebugInformation val = new MethodDebugInformation(method);
			val.code_size = ReadCodeSize(method);
			ScopeDebugInformation[] scopes = ReadScopes(methodByToken, val);
			ReadLineNumbers(methodByToken, val);
			ReadLocalVariables(methodByToken, scopes);
			return val;
		}

		private static int ReadCodeSize(MethodDefinition method)
		{
			return ((MemberReference)method).Module.Read<MethodDefinition, int>(method, (Func<MethodDefinition, MetadataReader, int>)((MethodDefinition m, MetadataReader reader) => reader.ReadCodeSize(m)));
		}

		private static void ReadLocalVariables(MethodEntry entry, ScopeDebugInformation[] scopes)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			LocalVariableEntry[] locals = entry.GetLocals();
			for (int i = 0; i < locals.Length; i++)
			{
				LocalVariableEntry localVariableEntry = locals[i];
				VariableDebugInformation val = new VariableDebugInformation(localVariableEntry.Index, localVariableEntry.Name);
				int blockIndex = localVariableEntry.BlockIndex;
				if (blockIndex >= 0 && blockIndex < scopes.Length)
				{
					ScopeDebugInformation val2 = scopes[blockIndex];
					if (val2 != null)
					{
						val2.Variables.Add(val);
					}
				}
			}
		}

		private void ReadLineNumbers(MethodEntry entry, MethodDebugInformation info)
		{
			LineNumberTable lineNumberTable = entry.GetLineNumberTable();
			info.sequence_points = new Collection<SequencePoint>(lineNumberTable.LineNumbers.Length);
			for (int i = 0; i < lineNumberTable.LineNumbers.Length; i++)
			{
				LineNumberEntry lineNumberEntry = lineNumberTable.LineNumbers[i];
				if (i <= 0 || lineNumberTable.LineNumbers[i - 1].Offset != lineNumberEntry.Offset)
				{
					info.sequence_points.Add(LineToSequencePoint(lineNumberEntry));
				}
			}
		}

		private Document GetDocument(SourceFileEntry file)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			string fileName = file.FileName;
			if (documents.TryGetValue(fileName, out var value))
			{
				return value;
			}
			value = new Document(fileName)
			{
				Hash = file.Checksum
			};
			documents.Add(fileName, value);
			return value;
		}

		private static ScopeDebugInformation[] ReadScopes(MethodEntry entry, MethodDebugInformation info)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0039: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_006d: 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)
			CodeBlockEntry[] codeBlocks = entry.GetCodeBlocks();
			ScopeDebugInformation[] array = (ScopeDebugInformation[])(object)new ScopeDebugInformation[codeBlocks.Length + 1];
			ScopeDebugInformation val = new ScopeDebugInformation
			{
				Start = new InstructionOffset(0),
				End = new InstructionOffset(info.code_size)
			};
			ScopeDebugInformation scope = val;
			array[0] = val;
			info.scope = scope;
			CodeBlockEntry[] array2 = codeBlocks;
			foreach (CodeBlockEntry codeBlockEntry in array2)
			{
				if (codeBlockEntry.BlockType == CodeBlockEntry.Type.Lexical || codeBlockEntry.BlockType == CodeBlockEntry.Type.CompilerGenerated)
				{
					ScopeDebugInformation val2 = new ScopeDebugInformation();
					val2.Start = new InstructionOffset(codeBlockEntry.StartOffset);
					val2.End = new InstructionOffset(codeBlockEntry.EndOffset);
					array[codeBlockEntry.Index + 1] = val2;
					if (!AddScope(info.scope.Scopes, val2))
					{
						info.scope.Scopes.Add(val2);
					}
				}
			}
			return array;
		}

		private static bool AddScope(Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<ScopeDebugInformation> enumerator = scopes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ScopeDebugInformation current = enumerator.Current;
					if (current.HasScopes && AddScope(current.Scopes, scope))
					{
						return true;
					}
					InstructionOffset val = scope.Start;
					int offset = ((InstructionOffset)(ref val)).Offset;
					val = current.Start;
					if (offset >= ((InstructionOffset)(ref val)).Offset)
					{
						val = scope.End;
						int offset2 = ((InstructionOffset)(ref val)).Offset;
						val = current.End;
						if (offset2 <= ((InstructionOffset)(ref val)).Offset)
						{
							current.Scopes.Add(scope);
							return true;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return false;
		}

		private SequencePoint LineToSequencePoint(LineNumberEntry line)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			SourceFileEntry sourceFile = symbol_file.GetSourceFile(line.File);
			return new SequencePoint(line.Offset, GetDocument(sourceFile))
			{
				StartLine = line.Row,
				EndLine = line.EndRow,
				StartColumn = line.Column,
				EndColumn = line.EndColumn
			};
		}

		public void Dispose()
		{
			symbol_file.Dispose();
		}
	}
	internal static class MethodEntryExtensions
	{
		public static bool HasColumnInfo(this MethodEntry entry)
		{
			return (entry.MethodFlags & MethodEntry.Flags.ColumnsInfoIncluded) != 0;
		}

		public static bool HasEndInfo(this MethodEntry entry)
		{
			return (entry.MethodFlags & MethodEntry.Flags.EndInfoIncluded) != 0;
		}
	}
	public sealed class MdbWriterProvider : ISymbolWriterProvider
	{
		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName)
		{
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			return (ISymbolWriter)(object)new MdbWriter(module.Mvid, fileName);
		}

		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream)
		{
			throw new NotImplementedException();
		}
	}
	public sealed class MdbWriter : ISymbolWriter, IDisposable
	{
		private class SourceFile : ISourceFile
		{
			private readonly CompileUnitEntry compilation_unit;

			private readonly SourceFileEntry entry;

			public SourceFileEntry Entry => entry;

			public CompileUnitEntry CompilationUnit => compilation_unit;

			public SourceFile(CompileUnitEntry comp_unit, SourceFileEntry entry)
			{
				compilation_unit = comp_unit;
				this.entry = entry;
			}
		}

		private class SourceMethod : IMethodDef
		{
			private readonly MethodDefinition method;

			public string Name => ((MemberReference)method).Name;

			public int Token
			{
				get
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					MetadataToken metadataToken = ((MemberReference)method).MetadataToken;
					return ((MetadataToken)(ref metadataToken)).ToInt32();
				}
			}

			public SourceMethod(MethodDefinition method)
			{
				this.method = method;
			}
		}

		private readonly Guid mvid;

		private readonly MonoSymbolWriter writer;

		private readonly Dictionary<string, SourceFile> source_files;

		public MdbWriter(Guid mvid, string assembly)
		{
			this.mvid = mvid;
			writer = new MonoSymbolWriter(assembly);
			source_files = new Dictionary<string, SourceFile>();
		}

		public ISymbolReaderProvider GetReaderProvider()
		{
			return (ISymbolReaderProvider)(object)new MdbReaderProvider();
		}

		private SourceFile GetSourceFile(Document document)
		{
			string url = document.Url;
			if (source_files.TryGetValue(url, out var value))
			{
				return value;
			}
			SourceFileEntry sourceFileEntry = writer.DefineDocument(url, null, (document.Hash != null && document.Hash.Length == 16) ? document.Hash : null);
			value = new SourceFile(writer.DefineCompilationUnit(sourceFileEntry), sourceFileEntry);
			source_files.Add(url, value);
			return value;
		}

		private void Populate(Collection<SequencePoint> sequencePoints, int[] offsets, int[] startRows, int[] endRows, int[] startCols, int[] endCols, out SourceFile file)
		{
			SourceFile sourceFile = null;
			for (int i = 0; i < sequencePoints.Count; i++)
			{
				SequencePoint val = sequencePoints[i];
				offsets[i] = val.Offset;
				if (sourceFile == null)
				{
					sourceFile = GetSourceFile(val.Document);
				}
				startRows[i] = val.StartLine;
				endRows[i] = val.EndLine;
				startCols[i] = val.StartColumn;
				endCols[i] = val.EndColumn;
			}
			file = sourceFile;
		}

		public void Write(MethodDebugInformation info)
		{
			SourceMethod method = new SourceMethod(info.method);
			Collection<SequencePoint> sequencePoints = info.SequencePoints;
			int count = sequencePoints.Count;
			if (count != 0)
			{
				int[] array = new int[count];
				int[] array2 = new int[count];
				int[] array3 = new int[count];
				int[] array4 = new int[count];
				int[] array5 = new int[count];
				Populate(sequencePoints, array, array2, array3, array4, array5, out var file);
				SourceMethodBuilder sourceMethodBuilder = writer.OpenMethod(file.CompilationUnit, 0, method);
				for (int i = 0; i < count; i++)
				{
					sourceMethodBuilder.MarkSequencePoint(array[i], file.CompilationUnit.SourceFile, array2[i], array4[i], array3[i], array5[i], is_hidden: false);
				}
				if (info.scope != null)
				{
					WriteRootScope(info.scope, info);
				}
				writer.CloseMethod();
			}
		}

		private void WriteRootScope(ScopeDebugInformation scope, MethodDebugInformation info)
		{
			WriteScopeVariables(scope);
			if (scope.HasScopes)
			{
				WriteScopes(scope.Scopes, info);
			}
		}

		private void WriteScope(ScopeDebugInformation scope, MethodDebugInformation info)
		{
			//IL_0007: 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)
			//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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			MonoSymbolWriter monoSymbolWriter = writer;
			InstructionOffset val = scope.Start;
			monoSymbolWriter.OpenScope(((InstructionOffset)(ref val)).Offset);
			WriteScopeVariables(scope);
			if (scope.HasScopes)
			{
				WriteScopes(scope.Scopes, info);
			}
			MonoSymbolWriter monoSymbolWriter2 = writer;
			val = scope.End;
			int end_offset;
			if (!((InstructionOffset)(ref val)).IsEndOfMethod)
			{
				val = scope.End;
				end_offset = ((InstructionOffset)(ref val)).Offset;
			}
			else
			{
				end_offset = info.code_size;
			}
			monoSymbolWriter2.CloseScope(end_offset);
		}

		private void WriteScopes(Collection<ScopeDebugInformation> scopes, MethodDebugInformation info)
		{
			for (int i = 0; i < scopes.Count; i++)
			{
				WriteScope(scopes[i], info);
			}
		}

		private void WriteScopeVariables(ScopeDebugInformation scope)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!scope.HasVariables)
			{
				return;
			}
			Enumerator<VariableDebugInformation> enumerator = scope.variables.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					VariableDebugInformation current = enumerator.Current;
					if (!string.IsNullOrEmpty(current.Name))
					{
						writer.DefineLocalVariable(current.Index, current.Name);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public ImageDebugHeader GetDebugHeader()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			return new ImageDebugHeader();
		}

		public void Dispose()
		{
			writer.WriteSymbolFile(mvid);
		}
	}
}

BepInEx/core/Mono.Cecil.Pdb.dll

Decompiled 8 months 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.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using Microsoft.Cci;
using Microsoft.Cci.Pdb;
using Mono.Cecil.Cil;
using Mono.Cecil.PE;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("Mono.Cecil")]
[assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("0.10.4.0")]
[assembly: AssemblyInformationalVersion("0.10.4.0")]
[assembly: AssemblyTitle("Mono.Cecil.Pdb")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyVersion("0.10.4.0")]
namespace Mono.Cecil.Pdb
{
	[ComImport]
	[Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface ISymUnmanagedDocumentWriter
	{
	}
	[ComImport]
	[Guid("0B97726E-9E6D-4f05-9A26-424022093CAA")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface ISymUnmanagedWriter2
	{
		void DefineDocument([In][MarshalAs(UnmanagedType.LPWStr)] string url, [In] ref Guid langauge, [In] ref Guid languageVendor, [In] ref Guid documentType, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedDocumentWriter pRetVal);

		void SetUserEntryPoint([In] int methodToken);

		void OpenMethod([In] int methodToken);

		void CloseMethod();

		void OpenScope([In] int startOffset, out int pRetVal);

		void CloseScope([In] int endOffset);

		void SetScopeRange_Placeholder();

		void DefineLocalVariable_Placeholder();

		void DefineParameter_Placeholder();

		void DefineField_Placeholder();

		void DefineGlobalVariable_Placeholder();

		void Close();

		void SetSymAttribute(uint parent, string name, uint data, IntPtr signature);

		void OpenNamespace([In][MarshalAs(UnmanagedType.LPWStr)] string name);

		void CloseNamespace();

		void UsingNamespace([In][MarshalAs(UnmanagedType.LPWStr)] string fullName);

		void SetMethodSourceRange_Placeholder();

		void Initialize([In][MarshalAs(UnmanagedType.IUnknown)] object emitter, [In][MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream, [In] bool fFullBuild);

		void GetDebugInfo(out ImageDebugDirectory pIDD, [In] int cData, out int pcData, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data);

		void DefineSequencePoints([In][MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, [In] int spCount, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] offsets, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] lines, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] columns, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endLines, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endColumns);

		void RemapToken_Placeholder();

		void Initialize2_Placeholder();

		void DefineConstant_Placeholder();

		void Abort_Placeholder();

		void DefineLocalVariable2([In][MarshalAs(UnmanagedType.LPWStr)] string name, [In] int attributes, [In] int sigToken, [In] int addrKind, [In] int addr1, [In] int addr2, [In] int addr3, [In] int startOffset, [In] int endOffset);

		void DefineGlobalVariable2_Placeholder();

		void DefineConstant2([In][MarshalAs(UnmanagedType.LPWStr)] string name, [In][MarshalAs(UnmanagedType.Struct)] object variant, [In] int sigToken);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")]
	internal interface IMetaDataEmit
	{
		void SetModuleProps(string szName);

		void Save(string szFile, uint dwSaveFlags);

		void SaveToStream(IntPtr pIStream, uint dwSaveFlags);

		uint GetSaveSize(uint fSave);

		uint DefineTypeDef(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements);

		uint DefineNestedType(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser);

		void SetHandler([In][MarshalAs(UnmanagedType.IUnknown)] object pUnk);

		uint DefineMethod(uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags);

		void DefineMethodImpl(uint td, uint tkBody, uint tkDecl);

		uint DefineTypeRefByName(uint tkResolutionScope, IntPtr szName);

		uint DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit);

		uint DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob);

		uint DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent);

		uint DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods);

		void SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize);

		void DeleteClassLayout(uint td);

		void SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType);

		void DeleteFieldMarshal(uint tk);

		uint DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission);

		void SetRVA(uint md, uint ulRVA);

		uint GetTokenFromSig(IntPtr pvSig, uint cbSig);

		uint DefineModuleRef(string szName);

		void SetParent(uint mr, uint tk);

		uint GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig);

		void SaveToMemory(IntPtr pbData, uint cbData);

		uint DefineUserString(string szString, uint cchString);

		void DeleteToken(uint tkObj);

		void SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags);

		void SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements);

		void SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods);

		uint SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission);

		void DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);

		void SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);

		void DeletePinvokeMap(uint tk);

		uint DefineCustomAttribute(uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute);

		void SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute);

		uint DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue);

		uint DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods);

		uint DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue);

		void SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue);

		void SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods);

		void SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue);

		uint DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs);

		void ApplyEditAndContinue([MarshalAs(UnmanagedType.IUnknown)] object pImport);

		uint TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax);

		void SetMethodImplFlags(uint md, uint dwImplFlags);

		void SetFieldRVA(uint fd, uint ulRVA);

		void Merge(IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs(UnmanagedType.IUnknown)] object pHandler);

		void MergeEnd();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
	internal interface IMetaDataImport
	{
		[PreserveSig]
		void CloseEnum(uint hEnum);

		uint CountEnum(uint hEnum);

		void ResetEnum(uint hEnum, uint ulPos);

		uint EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax);

		uint EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax);

		uint EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax);

		uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass);

		Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName);

		uint GetModuleFromScope();

		uint GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);

		uint GetInterfaceImplProps(uint iiImpl, out uint pClass);

		uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);

		uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope);

		uint EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax);

		uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax);

		uint EnumMethods(ref uint phEnum, uint cl, IntPtr rMethods, uint cMax);

		uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax);

		uint EnumFields(ref uint phEnum, uint cl, IntPtr rFields, uint cMax);

		uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax);

		uint EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax);

		uint EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax);

		uint EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax);

		uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission, uint cMax);

		uint FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);

		uint FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);

		uint FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);

		uint FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);

		uint GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);

		uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob);

		uint EnumProperties(ref uint phEnum, uint td, IntPtr rProperties, uint cMax);

		uint EnumEvents(ref uint phEnum, uint td, IntPtr rEvents, uint cMax);

		uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax);

		uint EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax);

		uint GetMethodSemantics(uint mb, uint tkEventProp);

		uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset);

		uint GetFieldMarshal(uint tk, out IntPtr ppvNativeType);

		uint GetRVA(uint tk, out uint pulCodeRVA);

		uint GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission);

		uint GetSigFromToken(uint mdSig, out IntPtr ppvSig);

		uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName);

		uint EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax);

		uint GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig);

		uint GetNameFromToken(uint tk);

		uint EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax);

		uint GetUserString(uint stk, StringBuilder szString, uint cchString);

		uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName);

		uint EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax);

		uint EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax);

		uint EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax);

		[PreserveSig]
		int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam);

		uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax);

		uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob);

		uint FindTypeRef(uint tkResolutionScope, string szName);

		uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue);

		uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue);

		uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)] uint[] rmdOtherMethod, uint cMax);

		uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue);

		uint GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData);

		[PreserveSig]
		[return: MarshalAs(UnmanagedType.Bool)]
		bool IsValidToken(uint tk);

		uint GetNestedClassProps(uint tdNestedClass);

		uint GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig);

		int IsGlobal(uint pd);
	}
	internal class ModuleMetadata : IMetaDataEmit, IMetaDataImport
	{
		private readonly ModuleDefinition module;

		private Dictionary<uint, TypeDefinition> types;

		private Dictionary<uint, MethodDefinition> methods;

		public ModuleMetadata(ModuleDefinition module)
		{
			this.module = module;
		}

		private bool TryGetType(uint token, out TypeDefinition type)
		{
			if (types == null)
			{
				InitializeMetadata(module);
			}
			return types.TryGetValue(token, out type);
		}

		private bool TryGetMethod(uint token, out MethodDefinition method)
		{
			if (methods == null)
			{
				InitializeMetadata(module);
			}
			return methods.TryGetValue(token, out method);
		}

		private void InitializeMetadata(ModuleDefinition module)
		{
			//IL_0032: 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)
			types = new Dictionary<uint, TypeDefinition>();
			methods = new Dictionary<uint, MethodDefinition>();
			foreach (TypeDefinition type in module.GetTypes())
			{
				Dictionary<uint, TypeDefinition> dictionary = types;
				MetadataToken metadataToken = ((MemberReference)type).MetadataToken;
				dictionary.Add(((MetadataToken)(ref metadataToken)).ToUInt32(), type);
				InitializeMethods(type);
			}
		}

		private void InitializeMethods(TypeDefinition type)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					Dictionary<uint, MethodDefinition> dictionary = methods;
					MetadataToken metadataToken = ((MemberReference)current).MetadataToken;
					dictionary.Add(((MetadataToken)(ref metadataToken)).ToUInt32(), current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public void SetModuleProps(string szName)
		{
			throw new NotImplementedException();
		}

		public void Save(string szFile, uint dwSaveFlags)
		{
			throw new NotImplementedException();
		}

		public void SaveToStream(IntPtr pIStream, uint dwSaveFlags)
		{
			throw new NotImplementedException();
		}

		public uint GetSaveSize(uint fSave)
		{
			throw new NotImplementedException();
		}

		public uint DefineTypeDef(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements)
		{
			throw new NotImplementedException();
		}

		public uint DefineNestedType(IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser)
		{
			throw new NotImplementedException();
		}

		public void SetHandler(object pUnk)
		{
			throw new NotImplementedException();
		}

		public uint DefineMethod(uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags)
		{
			throw new NotImplementedException();
		}

		public void DefineMethodImpl(uint td, uint tkBody, uint tkDecl)
		{
			throw new NotImplementedException();
		}

		public uint DefineTypeRefByName(uint tkResolutionScope, IntPtr szName)
		{
			throw new NotImplementedException();
		}

		public uint DefineImportType(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit)
		{
			throw new NotImplementedException();
		}

		public uint DefineMemberRef(uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint DefineImportMember(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent)
		{
			throw new NotImplementedException();
		}

		public uint DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods)
		{
			throw new NotImplementedException();
		}

		public void SetClassLayout(uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize)
		{
			throw new NotImplementedException();
		}

		public void DeleteClassLayout(uint td)
		{
			throw new NotImplementedException();
		}

		public void SetFieldMarshal(uint tk, IntPtr pvNativeType, uint cbNativeType)
		{
			throw new NotImplementedException();
		}

		public void DeleteFieldMarshal(uint tk)
		{
			throw new NotImplementedException();
		}

		public uint DefinePermissionSet(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission)
		{
			throw new NotImplementedException();
		}

		public void SetRVA(uint md, uint ulRVA)
		{
			throw new NotImplementedException();
		}

		public uint GetTokenFromSig(IntPtr pvSig, uint cbSig)
		{
			throw new NotImplementedException();
		}

		public uint DefineModuleRef(string szName)
		{
			throw new NotImplementedException();
		}

		public void SetParent(uint mr, uint tk)
		{
			throw new NotImplementedException();
		}

		public uint GetTokenFromTypeSpec(IntPtr pvSig, uint cbSig)
		{
			throw new NotImplementedException();
		}

		public void SaveToMemory(IntPtr pbData, uint cbData)
		{
			throw new NotImplementedException();
		}

		public uint DefineUserString(string szString, uint cchString)
		{
			throw new NotImplementedException();
		}

		public void DeleteToken(uint tkObj)
		{
			throw new NotImplementedException();
		}

		public void SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags)
		{
			throw new NotImplementedException();
		}

		public void SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements)
		{
			throw new NotImplementedException();
		}

		public void SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods)
		{
			throw new NotImplementedException();
		}

		public uint SetPermissionSetProps(uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission)
		{
			throw new NotImplementedException();
		}

		public void DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
		{
			throw new NotImplementedException();
		}

		public void SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
		{
			throw new NotImplementedException();
		}

		public void DeletePinvokeMap(uint tk)
		{
			throw new NotImplementedException();
		}

		public uint DefineCustomAttribute(uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute)
		{
			throw new NotImplementedException();
		}

		public void SetCustomAttributeValue(uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute)
		{
			throw new NotImplementedException();
		}

		public uint DefineField(uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
		{
			throw new NotImplementedException();
		}

		public uint DefineProperty(uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods)
		{
			throw new NotImplementedException();
		}

		public uint DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
		{
			throw new NotImplementedException();
		}

		public void SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
		{
			throw new NotImplementedException();
		}

		public void SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods)
		{
			throw new NotImplementedException();
		}

		public void SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue)
		{
			throw new NotImplementedException();
		}

		public uint DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs)
		{
			throw new NotImplementedException();
		}

		public void ApplyEditAndContinue(object pImport)
		{
			throw new NotImplementedException();
		}

		public uint TranslateSigWithScope(IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax)
		{
			throw new NotImplementedException();
		}

		public void SetMethodImplFlags(uint md, uint dwImplFlags)
		{
			throw new NotImplementedException();
		}

		public void SetFieldRVA(uint fd, uint ulRVA)
		{
			throw new NotImplementedException();
		}

		public void Merge(IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler)
		{
			throw new NotImplementedException();
		}

		public void MergeEnd()
		{
			throw new NotImplementedException();
		}

		public void CloseEnum(uint hEnum)
		{
			throw new NotImplementedException();
		}

		public uint CountEnum(uint hEnum)
		{
			throw new NotImplementedException();
		}

		public void ResetEnum(uint hEnum, uint ulPos)
		{
			throw new NotImplementedException();
		}

		public uint EnumTypeDefs(ref uint phEnum, uint[] rTypeDefs, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumInterfaceImpls(ref uint phEnum, uint td, uint[] rImpls, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumTypeRefs(ref uint phEnum, uint[] rTypeRefs, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass)
		{
			throw new NotImplementedException();
		}

		public Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName)
		{
			throw new NotImplementedException();
		}

		public uint GetModuleFromScope()
		{
			throw new NotImplementedException();
		}

		public uint GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected I4, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetType(td, out var type))
			{
				Marshal.WriteInt16(szTypeDef, 0);
				pchTypeDef = 1u;
				return 0u;
			}
			WriteString(((TypeReference)type).IsNested ? ((MemberReference)type).Name : ((MemberReference)type).FullName, szTypeDef, cchTypeDef, out pchTypeDef);
			WriteIntPtr(pdwTypeDefFlags, (uint)(int)type.Attributes);
			if (type.BaseType == null)
			{
				return 0u;
			}
			MetadataToken metadataToken = ((MemberReference)type.BaseType).MetadataToken;
			return ((MetadataToken)(ref metadataToken)).ToUInt32();
		}

		private static void WriteIntPtr(IntPtr ptr, uint value)
		{
			if (!(ptr == IntPtr.Zero))
			{
				Marshal.WriteInt32(ptr, (int)value);
			}
		}

		private static void WriteString(string str, IntPtr buffer, uint bufferSize, out uint chars)
		{
			uint num = ((str.Length + 1 >= bufferSize) ? (bufferSize - 1) : ((uint)str.Length));
			chars = num + 1;
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				Marshal.WriteInt16(buffer, num2, str[i]);
				num2 += 2;
			}
			Marshal.WriteInt16(buffer, num2, 0);
		}

		public uint GetInterfaceImplProps(uint iiImpl, out uint pClass)
		{
			throw new NotImplementedException();
		}

		public uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName)
		{
			throw new NotImplementedException();
		}

		public uint ResolveTypeRef(uint tr, ref Guid riid, out object ppIScope)
		{
			throw new NotImplementedException();
		}

		public uint EnumMembers(ref uint phEnum, uint cl, uint[] rMembers, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, uint[] rMembers, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMethods(ref uint phEnum, uint cl, IntPtr rMethods, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, uint[] rMethods, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumFields(ref uint phEnum, uint cl, IntPtr rFields, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, uint[] rFields, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumParams(ref uint phEnum, uint mb, uint[] rParams, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMemberRefs(ref uint phEnum, uint tkParent, uint[] rMemberRefs, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMethodImpls(ref uint phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint FindMember(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint FindMethod(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint FindField(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint FindMemberRef(uint td, string szName, byte[] pvSigBlob, uint cbSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected I4, but got Unknown
			if (!TryGetMethod(mb, out var method))
			{
				Marshal.WriteInt16(szMethod, 0);
				pchMethod = 1u;
				pClass = 0u;
				return 0u;
			}
			MetadataToken metadataToken = ((MemberReference)method.DeclaringType).MetadataToken;
			pClass = ((MetadataToken)(ref metadataToken)).ToUInt32();
			WriteString(((MemberReference)method).Name, szMethod, cchMethod, out pchMethod);
			WriteIntPtr(pdwAttr, (uint)(int)method.Attributes);
			WriteIntPtr(pulCodeRVA, (uint)method.RVA);
			return (uint)(int)method.ImplAttributes;
		}

		public uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob)
		{
			throw new NotImplementedException();
		}

		public uint EnumProperties(ref uint phEnum, uint td, IntPtr rProperties, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumEvents(ref uint phEnum, uint td, IntPtr rEvents, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint EnumMethodSemantics(ref uint phEnum, uint mb, uint[] rEventProp, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint GetMethodSemantics(uint mb, uint tkEventProp)
		{
			throw new NotImplementedException();
		}

		public uint GetClassLayout(uint td, out uint pdwPackSize, IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset)
		{
			throw new NotImplementedException();
		}

		public uint GetFieldMarshal(uint tk, out IntPtr ppvNativeType)
		{
			throw new NotImplementedException();
		}

		public uint GetRVA(uint tk, out uint pulCodeRVA)
		{
			throw new NotImplementedException();
		}

		public uint GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission)
		{
			throw new NotImplementedException();
		}

		public uint GetSigFromToken(uint mdSig, out IntPtr ppvSig)
		{
			throw new NotImplementedException();
		}

		public uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName)
		{
			throw new NotImplementedException();
		}

		public uint EnumModuleRefs(ref uint phEnum, uint[] rModuleRefs, uint cmax)
		{
			throw new NotImplementedException();
		}

		public uint GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig)
		{
			throw new NotImplementedException();
		}

		public uint GetNameFromToken(uint tk)
		{
			throw new NotImplementedException();
		}

		public uint EnumUnresolvedMethods(ref uint phEnum, uint[] rMethods, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint GetUserString(uint stk, StringBuilder szString, uint cchString)
		{
			throw new NotImplementedException();
		}

		public uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName)
		{
			throw new NotImplementedException();
		}

		public uint EnumSignatures(ref uint phEnum, uint[] rSignatures, uint cmax)
		{
			throw new NotImplementedException();
		}

		public uint EnumTypeSpecs(ref uint phEnum, uint[] rTypeSpecs, uint cmax)
		{
			throw new NotImplementedException();
		}

		public uint EnumUserStrings(ref uint phEnum, uint[] rStrings, uint cmax)
		{
			throw new NotImplementedException();
		}

		public int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam)
		{
			throw new NotImplementedException();
		}

		public uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob)
		{
			throw new NotImplementedException();
		}

		public uint FindTypeRef(uint tkResolutionScope, string szName)
		{
			throw new NotImplementedException();
		}

		public uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
		{
			throw new NotImplementedException();
		}

		public uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
		{
			throw new NotImplementedException();
		}

		public uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax)
		{
			throw new NotImplementedException();
		}

		public uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue)
		{
			throw new NotImplementedException();
		}

		public uint GetCustomAttributeByName(uint tkObj, string szName, out IntPtr ppData)
		{
			throw new NotImplementedException();
		}

		public bool IsValidToken(uint tk)
		{
			throw new NotImplementedException();
		}

		public uint GetNestedClassProps(uint tdNestedClass)
		{
			//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)
			if (!TryGetType(tdNestedClass, out var type))
			{
				return 0u;
			}
			if (!((TypeReference)type).IsNested)
			{
				return 0u;
			}
			MetadataToken metadataToken = ((MemberReference)type.DeclaringType).MetadataToken;
			return ((MetadataToken)(ref metadataToken)).ToUInt32();
		}

		public uint GetNativeCallConvFromSig(IntPtr pvSig, uint cbSig)
		{
			throw new NotImplementedException();
		}

		public int IsGlobal(uint pd)
		{
			throw new NotImplementedException();
		}
	}
	public class NativePdbReader : ISymbolReader, IDisposable
	{
		private int age;

		private Guid guid;

		private readonly Disposable<Stream> pdb_file;

		private readonly Dictionary<string, Document> documents = new Dictionary<string, Document>();

		private readonly Dictionary<uint, PdbFunction> functions = new Dictionary<uint, PdbFunction>();

		private readonly Dictionary<PdbScope, ImportDebugInformation> imports = new Dictionary<PdbScope, ImportDebugInformation>();

		internal NativePdbReader(Disposable<Stream> file)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			pdb_file = file;
		}

		public ISymbolWriterProvider GetWriterProvider()
		{
			return (ISymbolWriterProvider)(object)new NativePdbWriterProvider();
		}

		public bool ProcessDebugHeader(ImageDebugHeader header)
		{
			//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_0022: Invalid comparison between Unknown and I4
			if (!header.HasEntries)
			{
				return false;
			}
			ImageDebugHeaderEntry codeViewEntry = Mixin.GetCodeViewEntry(header);
			if (codeViewEntry == null)
			{
				return false;
			}
			if ((int)codeViewEntry.Directory.Type != 2)
			{
				return false;
			}
			byte[] data = codeViewEntry.Data;
			if (data.Length < 24)
			{
				return false;
			}
			if (ReadInt32(data, 0) != 1396986706)
			{
				return false;
			}
			byte[] array = new byte[16];
			Buffer.BlockCopy(data, 4, array, 0, 16);
			guid = new Guid(array);
			age = ReadInt32(data, 20);
			return PopulateFunctions();
		}

		private static int ReadInt32(byte[] bytes, int start)
		{
			return bytes[start] | (bytes[start + 1] << 8) | (bytes[start + 2] << 16) | (bytes[start + 3] << 24);
		}

		private bool PopulateFunctions()
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			Disposable<Stream> val = pdb_file;
			try
			{
				Dictionary<uint, PdbTokenLine> tokenToSourceMapping;
				string sourceServerData;
				int num;
				Guid guid;
				PdbFunction[] array = PdbFile.LoadFunctions(pdb_file.value, out tokenToSourceMapping, out sourceServerData, out num, out guid);
				if (this.guid != guid)
				{
					return false;
				}
				PdbFunction[] array2 = array;
				foreach (PdbFunction pdbFunction in array2)
				{
					functions.Add(pdbFunction.token, pdbFunction);
				}
			}
			finally
			{
				((IDisposable)val).Dispose();
			}
			return true;
		}

		public MethodDebugInformation Read(MethodDefinition method)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_007b: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			MetadataToken metadataToken = ((MemberReference)method).MetadataToken;
			if (!functions.TryGetValue(((MetadataToken)(ref metadataToken)).ToUInt32(), out var value))
			{
				return null;
			}
			MethodDebugInformation val = new MethodDebugInformation(method);
			ReadSequencePoints(value, val);
			val.scope = (ScopeDebugInformation)((!Mixin.IsNullOrEmpty<PdbScope>(value.scopes)) ? ((object)ReadScopeAndLocals(value.scopes[0], val)) : ((object)new ScopeDebugInformation
			{
				Start = new InstructionOffset(0),
				End = new InstructionOffset((int)value.length)
			}));
			uint tokenOfMethodWhoseUsingInfoAppliesToThisMethod = value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod;
			MetadataToken metadataToken2 = ((MemberReference)method).MetadataToken;
			if (tokenOfMethodWhoseUsingInfoAppliesToThisMethod != ((MetadataToken)(ref metadataToken2)).ToUInt32() && value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != 0)
			{
				val.scope.import = GetImport(value.tokenOfMethodWhoseUsingInfoAppliesToThisMethod, ((MemberReference)method).Module);
			}
			if (value.scopes.Length > 1)
			{
				for (int i = 1; i < value.scopes.Length; i++)
				{
					ScopeDebugInformation val2 = ReadScopeAndLocals(value.scopes[i], val);
					if (!AddScope(val.scope.Scopes, val2))
					{
						val.scope.Scopes.Add(val2);
					}
				}
			}
			if (value.iteratorScopes != null)
			{
				StateMachineScopeDebugInformation val3 = new StateMachineScopeDebugInformation();
				foreach (ILocalScope iteratorScope in value.iteratorScopes)
				{
					val3.Scopes.Add(new StateMachineScope((int)iteratorScope.Offset, (int)(iteratorScope.Offset + iteratorScope.Length + 1)));
				}
				((DebugInformation)val).CustomDebugInformations.Add((CustomDebugInformation)(object)val3);
			}
			if (value.synchronizationInformation != null)
			{
				AsyncMethodBodyDebugInformation val4 = new AsyncMethodBodyDebugInformation((int)value.synchronizationInformation.GeneratedCatchHandlerOffset);
				PdbSynchronizationPoint[] synchronizationPoints = value.synchronizationInformation.synchronizationPoints;
				foreach (PdbSynchronizationPoint pdbSynchronizationPoint in synchronizationPoints)
				{
					val4.Yields.Add(new InstructionOffset((int)pdbSynchronizationPoint.SynchronizeOffset));
					val4.Resumes.Add(new InstructionOffset((int)pdbSynchronizationPoint.ContinuationOffset));
					val4.ResumeMethods.Add(method);
				}
				((DebugInformation)val).CustomDebugInformations.Add((CustomDebugInformation)(object)val4);
				val.StateMachineKickOffMethod = (MethodDefinition)((MemberReference)method).Module.LookupToken((int)value.synchronizationInformation.kickoffMethodToken);
			}
			return val;
		}

		private Collection<ScopeDebugInformation> ReadScopeAndLocals(PdbScope[] scopes, MethodDebugInformation info)
		{
			Collection<ScopeDebugInformation> val = new Collection<ScopeDebugInformation>(scopes.Length);
			foreach (PdbScope pdbScope in scopes)
			{
				if (pdbScope != null)
				{
					val.Add(ReadScopeAndLocals(pdbScope, info));
				}
			}
			return val;
		}

		private ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			ScopeDebugInformation val = new ScopeDebugInformation();
			val.Start = new InstructionOffset((int)scope.offset);
			val.End = new InstructionOffset((int)(scope.offset + scope.length));
			if (!Mixin.IsNullOrEmpty<PdbSlot>(scope.slots))
			{
				val.variables = new Collection<VariableDebugInformation>(scope.slots.Length);
				PdbSlot[] slots = scope.slots;
				foreach (PdbSlot pdbSlot in slots)
				{
					if ((pdbSlot.flags & 1) == 0)
					{
						VariableDebugInformation val2 = new VariableDebugInformation((int)pdbSlot.slot, pdbSlot.name);
						if ((pdbSlot.flags & 4u) != 0)
						{
							val2.IsDebuggerHidden = true;
						}
						val.variables.Add(val2);
					}
				}
			}
			if (!Mixin.IsNullOrEmpty<PdbConstant>(scope.constants))
			{
				val.constants = new Collection<ConstantDebugInformation>(scope.constants.Length);
				PdbConstant[] constants = scope.constants;
				foreach (PdbConstant pdbConstant in constants)
				{
					TypeReference val3 = ((MemberReference)info.Method).Module.Read<PdbConstant, TypeReference>(pdbConstant, (Func<PdbConstant, MetadataReader, TypeReference>)((PdbConstant c, MetadataReader r) => r.ReadConstantSignature(new MetadataToken(c.token))));
					object obj = pdbConstant.value;
					if (val3 != null && !val3.IsValueType && obj is int && (int)obj == 0)
					{
						obj = null;
					}
					val.constants.Add(new ConstantDebugInformation(pdbConstant.name, val3, obj));
				}
			}
			if (!Mixin.IsNullOrEmpty<string>(scope.usedNamespaces))
			{
				if (imports.TryGetValue(scope, out var value))
				{
					val.import = value;
				}
				else
				{
					value = GetImport(scope, ((MemberReference)info.Method).Module);
					imports.Add(scope, value);
					val.import = value;
				}
			}
			val.scopes = ReadScopeAndLocals(scope.scopes, info);
			return val;
		}

		private static bool AddScope(Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<ScopeDebugInformation> enumerator = scopes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ScopeDebugInformation current = enumerator.Current;
					if (current.HasScopes && AddScope(current.Scopes, scope))
					{
						return true;
					}
					InstructionOffset val = scope.Start;
					int offset = ((InstructionOffset)(ref val)).Offset;
					val = current.Start;
					if (offset >= ((InstructionOffset)(ref val)).Offset)
					{
						val = scope.End;
						int offset2 = ((InstructionOffset)(ref val)).Offset;
						val = current.End;
						if (offset2 <= ((InstructionOffset)(ref val)).Offset)
						{
							current.Scopes.Add(scope);
							return true;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return false;
		}

		private ImportDebugInformation GetImport(uint token, ModuleDefinition module)
		{
			if (!functions.TryGetValue(token, out var value))
			{
				return null;
			}
			if (value.scopes.Length != 1)
			{
				return null;
			}
			PdbScope pdbScope = value.scopes[0];
			if (imports.TryGetValue(pdbScope, out var value2))
			{
				return value2;
			}
			value2 = GetImport(pdbScope, module);
			imports.Add(pdbScope, value2);
			return value2;
		}

		private static ImportDebugInformation GetImport(PdbScope scope, ModuleDefinition module)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_007a: 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_0089: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			if (Mixin.IsNullOrEmpty<string>(scope.usedNamespaces))
			{
				return null;
			}
			ImportDebugInformation val = new ImportDebugInformation();
			string[] usedNamespaces = scope.usedNamespaces;
			foreach (string text in usedNamespaces)
			{
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				ImportTarget val2 = null;
				string text2 = text.Substring(1);
				switch (text[0])
				{
				case 'U':
					val2 = new ImportTarget((ImportTargetKind)1)
					{
						@namespace = text2
					};
					break;
				case 'T':
				{
					TypeReference val4 = TypeParser.ParseType(module, text2, false);
					if (val4 != null)
					{
						val2 = new ImportTarget((ImportTargetKind)3)
						{
							type = val4
						};
					}
					break;
				}
				case 'A':
				{
					int num = text.IndexOf(' ');
					if (num < 0)
					{
						val2 = new ImportTarget((ImportTargetKind)1)
						{
							@namespace = text
						};
						break;
					}
					string alias = text.Substring(1, num - 1);
					string text3 = text.Substring(num + 2);
					switch (text[num + 1])
					{
					case 'U':
						val2 = new ImportTarget((ImportTargetKind)7)
						{
							alias = alias,
							@namespace = text3
						};
						break;
					case 'T':
					{
						TypeReference val3 = TypeParser.ParseType(module, text3, false);
						if (val3 != null)
						{
							val2 = new ImportTarget((ImportTargetKind)9)
							{
								alias = alias,
								type = val3
							};
						}
						break;
					}
					}
					break;
				}
				case '*':
					val2 = new ImportTarget((ImportTargetKind)1)
					{
						@namespace = text2
					};
					break;
				case '@':
					if (!text2.StartsWith("P:"))
					{
						continue;
					}
					val2 = new ImportTarget((ImportTargetKind)1)
					{
						@namespace = text2.Substring(2)
					};
					break;
				}
				if (val2 != null)
				{
					val.Targets.Add(val2);
				}
			}
			return val;
		}

		private void ReadSequencePoints(PdbFunction function, MethodDebugInformation info)
		{
			if (function.lines != null)
			{
				info.sequence_points = new Collection<SequencePoint>();
				PdbLines[] lines = function.lines;
				foreach (PdbLines lines2 in lines)
				{
					ReadLines(lines2, info);
				}
			}
		}

		private void ReadLines(PdbLines lines, MethodDebugInformation info)
		{
			Document document = GetDocument(lines.file);
			PdbLine[] lines2 = lines.lines;
			for (int i = 0; i < lines2.Length; i++)
			{
				ReadLine(lines2[i], document, info);
			}
		}

		private static void ReadLine(PdbLine line, Document document, MethodDebugInformation info)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			SequencePoint val = new SequencePoint((int)line.offset, document);
			val.StartLine = (int)line.lineBegin;
			val.StartColumn = line.colBegin;
			val.EndLine = (int)line.lineEnd;
			val.EndColumn = line.colEnd;
			info.sequence_points.Add(val);
		}

		private Document GetDocument(PdbSource source)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			string name = source.name;
			if (documents.TryGetValue(name, out var value))
			{
				return value;
			}
			value = new Document(name)
			{
				Language = PdbGuidMapping.ToLanguage(source.language),
				LanguageVendor = PdbGuidMapping.ToVendor(source.vendor),
				Type = PdbGuidMapping.ToType(source.doctype)
			};
			documents.Add(name, value);
			return value;
		}

		public void Dispose()
		{
			//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)
			pdb_file.Dispose();
		}
	}
	public class NativePdbWriter : ISymbolWriter, IDisposable
	{
		private readonly ModuleDefinition module;

		private readonly MetadataBuilder metadata;

		private readonly SymWriter writer;

		private readonly Dictionary<string, SymDocumentWriter> documents;

		private readonly Dictionary<ImportDebugInformation, MetadataToken> import_info_to_parent;

		internal NativePdbWriter(ModuleDefinition module, SymWriter writer)
		{
			this.module = module;
			metadata = module.metadata_builder;
			this.writer = writer;
			documents = new Dictionary<string, SymDocumentWriter>();
			import_info_to_parent = new Dictionary<ImportDebugInformation, MetadataToken>();
		}

		public ISymbolReaderProvider GetReaderProvider()
		{
			return (ISymbolReaderProvider)(object)new NativePdbReaderProvider();
		}

		public ImageDebugHeader GetDebugHeader()
		{
			//IL_0020: 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_002c: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			ImageDebugDirectory idd;
			byte[] debugInfo = writer.GetDebugInfo(out idd);
			idd.TimeDateStamp = (int)module.timestamp;
			return new ImageDebugHeader(new ImageDebugHeaderEntry(idd, debugInfo));
		}

		public void Write(MethodDebugInformation info)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			MetadataToken metadataToken = ((MemberReference)info.method).MetadataToken;
			int methodToken = ((MetadataToken)(ref metadataToken)).ToInt32();
			if (info.HasSequencePoints || info.scope != null || ((DebugInformation)info).HasCustomDebugInformations || info.StateMachineKickOffMethod != null)
			{
				writer.OpenMethod(methodToken);
				if (!Mixin.IsNullOrEmpty<SequencePoint>(info.sequence_points))
				{
					DefineSequencePoints(info.sequence_points);
				}
				MetadataToken import_parent = default(MetadataToken);
				if (info.scope != null)
				{
					DefineScope(info.scope, info, out import_parent);
				}
				DefineCustomMetadata(info, import_parent);
				writer.CloseMethod();
			}
		}

		private void DefineCustomMetadata(MethodDebugInformation info, MetadataToken import_parent)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			CustomMetadataWriter customMetadataWriter = new CustomMetadataWriter(writer);
			if (((MetadataToken)(ref import_parent)).RID != 0)
			{
				customMetadataWriter.WriteForwardInfo(import_parent);
			}
			else if (info.scope != null && info.scope.Import != null && info.scope.Import.HasTargets)
			{
				customMetadataWriter.WriteUsingInfo(info.scope.Import);
			}
			if (info.Method.HasCustomAttributes)
			{
				Enumerator<CustomAttribute> enumerator = info.Method.CustomAttributes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CustomAttribute current = enumerator.Current;
						TypeReference attributeType = current.AttributeType;
						if (Mixin.IsTypeOf(attributeType, "System.Runtime.CompilerServices", "IteratorStateMachineAttribute") || Mixin.IsTypeOf(attributeType, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute"))
						{
							CustomAttributeArgument val = current.ConstructorArguments[0];
							object value = ((CustomAttributeArgument)(ref val)).Value;
							TypeReference val2 = (TypeReference)((value is TypeReference) ? value : null);
							if (val2 != null)
							{
								customMetadataWriter.WriteForwardIterator(val2);
							}
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			if (((DebugInformation)info).HasCustomDebugInformations)
			{
				CustomDebugInformation? obj = ((IEnumerable<CustomDebugInformation>)((DebugInformation)info).CustomDebugInformations).FirstOrDefault((Func<CustomDebugInformation, bool>)((CustomDebugInformation cdi) => (int)cdi.Kind == 1));
				StateMachineScopeDebugInformation val3 = (StateMachineScopeDebugInformation)(object)((obj is StateMachineScopeDebugInformation) ? obj : null);
				if (val3 != null)
				{
					customMetadataWriter.WriteIteratorScopes(val3, info);
				}
			}
			customMetadataWriter.WriteCustomMetadata();
			DefineAsyncCustomMetadata(info);
		}

		private void DefineAsyncCustomMetadata(MethodDebugInformation info)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_004c: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (!((DebugInformation)info).HasCustomDebugInformations)
			{
				return;
			}
			Enumerator<CustomDebugInformation> enumerator = ((DebugInformation)info).CustomDebugInformations.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomDebugInformation current = enumerator.Current;
					AsyncMethodBodyDebugInformation val = (AsyncMethodBodyDebugInformation)(object)((current is AsyncMethodBodyDebugInformation) ? current : null);
					if (val == null)
					{
						continue;
					}
					using MemoryStream memoryStream = new MemoryStream();
					BinaryStreamWriter val2 = new BinaryStreamWriter((Stream)memoryStream);
					int num;
					MetadataToken metadataToken;
					if (info.StateMachineKickOffMethod == null)
					{
						num = 0;
					}
					else
					{
						metadataToken = ((MemberReference)info.StateMachineKickOffMethod).MetadataToken;
						num = (int)((MetadataToken)(ref metadataToken)).ToUInt32();
					}
					val2.WriteUInt32((uint)num);
					InstructionOffset val3 = val.CatchHandler;
					val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset);
					val2.WriteUInt32((uint)val.Resumes.Count);
					for (int i = 0; i < val.Resumes.Count; i++)
					{
						val3 = val.Yields[i];
						val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset);
						metadataToken = ((MemberReference)val.resume_methods[i]).MetadataToken;
						val2.WriteUInt32(((MetadataToken)(ref metadataToken)).ToUInt32());
						val3 = val.Resumes[i];
						val2.WriteUInt32((uint)((InstructionOffset)(ref val3)).Offset);
					}
					writer.DefineCustomMetadata("asyncMethodInfo", memoryStream.ToArray());
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		private void DefineScope(ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Invalid comparison between Unknown and I4
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			InstructionOffset val = scope.Start;
			int offset = ((InstructionOffset)(ref val)).Offset;
			val = scope.End;
			int num;
			if (!((InstructionOffset)(ref val)).IsEndOfMethod)
			{
				val = scope.End;
				num = ((InstructionOffset)(ref val)).Offset;
			}
			else
			{
				num = info.code_size;
			}
			int num2 = num;
			import_parent = new MetadataToken(0u);
			writer.OpenScope(offset);
			if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue(info.scope.Import, out import_parent))
			{
				Enumerator<ImportTarget> enumerator = scope.Import.Targets.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ImportTarget current = enumerator.Current;
						ImportTargetKind kind = current.Kind;
						if ((int)kind <= 3)
						{
							if ((int)kind != 1)
							{
								if ((int)kind == 3)
								{
									writer.UsingNamespace("T" + TypeParser.ToParseable(current.type, true));
								}
							}
							else
							{
								writer.UsingNamespace("U" + current.@namespace);
							}
						}
						else if ((int)kind != 7)
						{
							if ((int)kind == 9)
							{
								writer.UsingNamespace("A" + current.Alias + " T" + TypeParser.ToParseable(current.type, true));
							}
						}
						else
						{
							writer.UsingNamespace("A" + current.Alias + " U" + current.@namespace);
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				import_info_to_parent.Add(info.scope.Import, ((MemberReference)info.method).MetadataToken);
			}
			int local_var_token = ((MetadataToken)(ref info.local_var_token)).ToInt32();
			if (!Mixin.IsNullOrEmpty<VariableDebugInformation>(scope.variables))
			{
				for (int i = 0; i < scope.variables.Count; i++)
				{
					VariableDebugInformation variable = scope.variables[i];
					DefineLocalVariable(variable, local_var_token, offset, num2);
				}
			}
			if (!Mixin.IsNullOrEmpty<ConstantDebugInformation>(scope.constants))
			{
				for (int j = 0; j < scope.constants.Count; j++)
				{
					ConstantDebugInformation constant = scope.constants[j];
					DefineConstant(constant);
				}
			}
			if (!Mixin.IsNullOrEmpty<ScopeDebugInformation>(scope.scopes))
			{
				for (int k = 0; k < scope.scopes.Count; k++)
				{
					DefineScope(scope.scopes[k], info, out var _);
				}
			}
			writer.CloseScope(num2);
		}

		private void DefineSequencePoints(Collection<SequencePoint> sequence_points)
		{
			for (int i = 0; i < sequence_points.Count; i++)
			{
				SequencePoint val = sequence_points[i];
				writer.DefineSequencePoints(GetDocument(val.Document), new int[1] { val.Offset }, new int[1] { val.StartLine }, new int[1] { val.StartColumn }, new int[1] { val.EndLine }, new int[1] { val.EndColumn });
			}
		}

		private void DefineLocalVariable(VariableDebugInformation variable, int local_var_token, int start_offset, int end_offset)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			writer.DefineLocalVariable2(variable.Name, variable.Attributes, local_var_token, variable.Index, 0, 0, start_offset, end_offset);
		}

		private void DefineConstant(ConstantDebugInformation constant)
		{
			uint num = metadata.AddStandAloneSignature(metadata.GetConstantTypeBlobIndex(constant.ConstantType));
			MetadataToken val = default(MetadataToken);
			((MetadataToken)(ref val))..ctor((TokenType)285212672, num);
			writer.DefineConstant2(constant.Name, constant.Value, ((MetadataToken)(ref val)).ToInt32());
		}

		private SymDocumentWriter GetDocument(Document document)
		{
			if (document == null)
			{
				return null;
			}
			if (documents.TryGetValue(document.Url, out var value))
			{
				return value;
			}
			value = writer.DefineDocument(document.Url, document.LanguageGuid, document.LanguageVendorGuid, document.TypeGuid);
			documents[document.Url] = value;
			return value;
		}

		public void Dispose()
		{
			//IL_0016: 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)
			MethodDefinition entryPoint = module.EntryPoint;
			if (entryPoint != null)
			{
				SymWriter symWriter = writer;
				MetadataToken metadataToken = ((MemberReference)entryPoint).MetadataToken;
				symWriter.SetUserEntryPoint(((MetadataToken)(ref metadataToken)).ToInt32());
			}
			writer.Close();
		}
	}
	internal enum CustomMetadataType : byte
	{
		UsingInfo = 0,
		ForwardInfo = 1,
		IteratorScopes = 3,
		ForwardIterator = 4
	}
	internal class CustomMetadataWriter : IDisposable
	{
		private readonly SymWriter sym_writer;

		private readonly MemoryStream stream;

		private readonly BinaryStreamWriter writer;

		private int count;

		private const byte version = 4;

		public CustomMetadataWriter(SymWriter sym_writer)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			this.sym_writer = sym_writer;
			stream = new MemoryStream();
			writer = new BinaryStreamWriter((Stream)stream);
			writer.WriteByte((byte)4);
			writer.WriteByte((byte)0);
			writer.Align(4);
		}

		public void WriteUsingInfo(ImportDebugInformation import_info)
		{
			Write(CustomMetadataType.UsingInfo, delegate
			{
				writer.WriteUInt16((ushort)1);
				writer.WriteUInt16((ushort)import_info.Targets.Count);
			});
		}

		public void WriteForwardInfo(MetadataToken import_parent)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Write(CustomMetadataType.ForwardInfo, delegate
			{
				writer.WriteUInt32(((MetadataToken)(ref import_parent)).ToUInt32());
			});
		}

		public void WriteIteratorScopes(StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info)
		{
			Write(CustomMetadataType.IteratorScopes, delegate
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				Collection<StateMachineScope> scopes = state_machine.Scopes;
				writer.WriteInt32(scopes.Count);
				Enumerator<StateMachineScope> enumerator = scopes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						StateMachineScope current = enumerator.Current;
						InstructionOffset val = current.Start;
						int offset = ((InstructionOffset)(ref val)).Offset;
						val = current.End;
						int num;
						if (!((InstructionOffset)(ref val)).IsEndOfMethod)
						{
							val = current.End;
							num = ((InstructionOffset)(ref val)).Offset;
						}
						else
						{
							num = debug_info.code_size;
						}
						int num2 = num;
						writer.WriteInt32(offset);
						writer.WriteInt32(num2 - 1);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			});
		}

		public void WriteForwardIterator(TypeReference type)
		{
			Write(CustomMetadataType.ForwardIterator, delegate
			{
				writer.WriteBytes(Encoding.Unicode.GetBytes(((MemberReference)type).Name));
			});
		}

		private void Write(CustomMetadataType type, Action write)
		{
			count++;
			writer.WriteByte((byte)4);
			writer.WriteByte((byte)type);
			writer.Align(4);
			int position = writer.Position;
			writer.WriteUInt32(0u);
			write();
			writer.Align(4);
			int position2 = writer.Position;
			int num = position2 - position + 4;
			writer.Position = position;
			writer.WriteInt32(num);
			writer.Position = position2;
		}

		public void WriteCustomMetadata()
		{
			if (count != 0)
			{
				((BinaryWriter)(object)writer).BaseStream.Position = 1L;
				writer.WriteByte((byte)count);
				((BinaryWriter)(object)writer).Flush();
				sym_writer.DefineCustomMetadata("MD2", stream.ToArray());
			}
		}

		public void Dispose()
		{
			stream.Dispose();
		}
	}
	public sealed class NativePdbReaderProvider : ISymbolReaderProvider
	{
		public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			return (ISymbolReader)(object)new NativePdbReader(Disposable.Owned<Stream>((Stream)File.OpenRead(Mixin.GetPdbFileName(fileName))));
		}

		public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Mixin.CheckModule(module);
			Mixin.CheckStream((object)symbolStream);
			return (ISymbolReader)(object)new NativePdbReader(Disposable.NotOwned<Stream>(symbolStream));
		}
	}
	public sealed class PdbReaderProvider : ISymbolReaderProvider
	{
		public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName)
		{
			//IL_0048: 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)
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			if (module.HasDebugHeader && Mixin.GetEmbeddedPortablePdbEntry(module.GetDebugHeader()) != null)
			{
				return new EmbeddedPortablePdbReaderProvider().GetSymbolReader(module, fileName);
			}
			if (!Mixin.IsPortablePdb(Mixin.GetPdbFileName(fileName)))
			{
				return new NativePdbReaderProvider().GetSymbolReader(module, fileName);
			}
			return new PortablePdbReaderProvider().GetSymbolReader(module, fileName);
		}

		public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Mixin.CheckModule(module);
			Mixin.CheckStream((object)symbolStream);
			Mixin.CheckReadSeek(symbolStream);
			if (!Mixin.IsPortablePdb(symbolStream))
			{
				return new NativePdbReaderProvider().GetSymbolReader(module, symbolStream);
			}
			return new PortablePdbReaderProvider().GetSymbolReader(module, symbolStream);
		}
	}
	public sealed class NativePdbWriterProvider : ISymbolWriterProvider
	{
		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName)
		{
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			return (ISymbolWriter)(object)new NativePdbWriter(module, CreateWriter(module, Mixin.GetPdbFileName(fileName)));
		}

		private static SymWriter CreateWriter(ModuleDefinition module, string pdb)
		{
			SymWriter symWriter = new SymWriter();
			if (File.Exists(pdb))
			{
				File.Delete(pdb);
			}
			symWriter.Initialize(new ModuleMetadata(module), pdb, fFullBuild: true);
			return symWriter;
		}

		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream)
		{
			throw new NotImplementedException();
		}
	}
	public sealed class PdbWriterProvider : ISymbolWriterProvider
	{
		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Mixin.CheckModule(module);
			Mixin.CheckFileName(fileName);
			if (HasPortablePdbSymbols(module))
			{
				return new PortablePdbWriterProvider().GetSymbolWriter(module, fileName);
			}
			return new NativePdbWriterProvider().GetSymbolWriter(module, fileName);
		}

		private static bool HasPortablePdbSymbols(ModuleDefinition module)
		{
			if (module.symbol_reader != null)
			{
				return module.symbol_reader is PortablePdbReader;
			}
			return false;
		}

		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Mixin.CheckModule(module);
			Mixin.CheckStream((object)symbolStream);
			Mixin.CheckReadSeek(symbolStream);
			if (HasPortablePdbSymbols(module))
			{
				return new PortablePdbWriterProvider().GetSymbolWriter(module, symbolStream);
			}
			return new NativePdbWriterProvider().GetSymbolWriter(module, symbolStream);
		}
	}
	internal class SymDocumentWriter
	{
		private readonly ISymUnmanagedDocumentWriter m_unmanagedDocumentWriter;

		public SymDocumentWriter(ISymUnmanagedDocumentWriter unmanagedDocumentWriter)
		{
			m_unmanagedDocumentWriter = unmanagedDocumentWriter;
		}

		public ISymUnmanagedDocumentWriter GetUnmanaged()
		{
			return m_unmanagedDocumentWriter;
		}
	}
	internal class SymWriter
	{
		private static Guid s_symUnmangedWriterIID = new Guid("0b97726e-9e6d-4f05-9a26-424022093caa");

		private static Guid s_CorSymWriter_SxS_ClassID = new Guid("108296c1-281e-11d3-bd22-0000f80849bd");

		private readonly ISymUnmanagedWriter2 m_writer;

		private readonly Collection<ISymUnmanagedDocumentWriter> documents;

		[DllImport("ole32.dll")]
		private static extern int CoCreateInstance([In] ref Guid rclsid, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In] uint dwClsContext, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);

		public SymWriter()
		{
			CoCreateInstance(ref s_CorSymWriter_SxS_ClassID, null, 1u, ref s_symUnmangedWriterIID, out var ppv);
			m_writer = (ISymUnmanagedWriter2)ppv;
			documents = new Collection<ISymUnmanagedDocumentWriter>();
		}

		public byte[] GetDebugInfo(out ImageDebugDirectory idd)
		{
			m_writer.GetDebugInfo(out idd, 0, out var pcData, null);
			byte[] array = new byte[pcData];
			m_writer.GetDebugInfo(out idd, pcData, out pcData, array);
			return array;
		}

		public void DefineLocalVariable2(string name, VariableAttributes attributes, int sigToken, int addr1, int addr2, int addr3, int startOffset, int endOffset)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected I4, but got Unknown
			m_writer.DefineLocalVariable2(name, (int)attributes, sigToken, 1, addr1, addr2, addr3, startOffset, endOffset);
		}

		public void DefineConstant2(string name, object value, int sigToken)
		{
			if (value == null)
			{
				m_writer.DefineConstant2(name, 0, sigToken);
			}
			else
			{
				m_writer.DefineConstant2(name, value, sigToken);
			}
		}

		public void Close()
		{
			//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)
			m_writer.Close();
			Marshal.ReleaseComObject(m_writer);
			Enumerator<ISymUnmanagedDocumentWriter> enumerator = documents.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Marshal.ReleaseComObject(enumerator.Current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public void CloseMethod()
		{
			m_writer.CloseMethod();
		}

		public void CloseNamespace()
		{
			m_writer.CloseNamespace();
		}

		public void CloseScope(int endOffset)
		{
			m_writer.CloseScope(endOffset);
		}

		public SymDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType)
		{
			m_writer.DefineDocument(url, ref language, ref languageVendor, ref documentType, out var pRetVal);
			documents.Add(pRetVal);
			return new SymDocumentWriter(pRetVal);
		}

		public void DefineSequencePoints(SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns)
		{
			m_writer.DefineSequencePoints(document.GetUnmanaged(), offsets.Length, offsets, lines, columns, endLines, endColumns);
		}

		public void Initialize(object emitter, string filename, bool fFullBuild)
		{
			m_writer.Initialize(emitter, filename, null, fFullBuild);
		}

		public void SetUserEntryPoint(int methodToken)
		{
			m_writer.SetUserEntryPoint(methodToken);
		}

		public void OpenMethod(int methodToken)
		{
			m_writer.OpenMethod(methodToken);
		}

		public void OpenNamespace(string name)
		{
			m_writer.OpenNamespace(name);
		}

		public int OpenScope(int startOffset)
		{
			m_writer.OpenScope(startOffset, out var pRetVal);
			return pRetVal;
		}

		public void UsingNamespace(string fullName)
		{
			m_writer.UsingNamespace(fullName);
		}

		public void DefineCustomMetadata(string name, byte[] metadata)
		{
			GCHandle gCHandle = GCHandle.Alloc(metadata, GCHandleType.Pinned);
			m_writer.SetSymAttribute(0u, name, (uint)metadata.Length, gCHandle.AddrOfPinnedObject());
			gCHandle.Free();
		}
	}
}
namespace Microsoft.Cci
{
	public interface ILocalScope
	{
		uint Offset { get; }

		uint Length { get; }
	}
	public interface INamespaceScope
	{
		IEnumerable<IUsedNamespace> UsedNamespaces { get; }
	}
	public interface IUsedNamespace
	{
		IName Alias { get; }

		IName NamespaceName { get; }
	}
	public interface IName
	{
		int UniqueKey { get; }

		int UniqueKeyIgnoringCase { get; }

		string Value { get; }
	}
	internal sealed class PdbIteratorScope : ILocalScope
	{
		private uint offset;

		private uint length;

		public uint Offset => offset;

		public uint Length => length;

		internal PdbIteratorScope(uint offset, uint length)
		{
			this.offset = offset;
			this.length = length;
		}
	}
}
namespace Microsoft.Cci.Pdb
{
	internal class BitAccess
	{
		private byte[] buffer;

		private int offset;

		internal byte[] Buffer => buffer;

		internal int Position
		{
			get
			{
				return offset;
			}
			set
			{
				offset = value;
			}
		}

		internal BitAccess(int capacity)
		{
			buffer = new byte[capacity];
		}

		internal void FillBuffer(Stream stream, int capacity)
		{
			MinCapacity(capacity);
			stream.Read(buffer, 0, capacity);
			offset = 0;
		}

		internal void Append(Stream stream, int count)
		{
			int num = offset + count;
			if (buffer.Length < num)
			{
				byte[] destinationArray = new byte[num];
				Array.Copy(buffer, destinationArray, buffer.Length);
				buffer = destinationArray;
			}
			stream.Read(buffer, offset, count);
			offset += count;
		}

		internal void MinCapacity(int capacity)
		{
			if (buffer.Length < capacity)
			{
				buffer = new byte[capacity];
			}
			offset = 0;
		}

		internal void Align(int alignment)
		{
			while (offset % alignment != 0)
			{
				offset++;
			}
		}

		internal void ReadInt16(out short value)
		{
			value = (short)((buffer[offset] & 0xFF) | (buffer[offset + 1] << 8));
			offset += 2;
		}

		internal void ReadInt8(out sbyte value)
		{
			value = (sbyte)buffer[offset];
			offset++;
		}

		internal void ReadInt32(out int value)
		{
			value = (buffer[offset] & 0xFF) | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24);
			offset += 4;
		}

		internal void ReadInt64(out long value)
		{
			value = ((long)buffer[offset] & 0xFFL) | (long)((ulong)buffer[offset + 1] << 8) | (long)((ulong)buffer[offset + 2] << 16) | (long)((ulong)buffer[offset + 3] << 24) | (long)((ulong)buffer[offset + 4] << 32) | (long)((ulong)buffer[offset + 5] << 40) | (long)((ulong)buffer[offset + 6] << 48) | (long)((ulong)buffer[offset + 7] << 56);
			offset += 8;
		}

		internal void ReadUInt16(out ushort value)
		{
			value = (ushort)((buffer[offset] & 0xFFu) | (uint)(buffer[offset + 1] << 8));
			offset += 2;
		}

		internal void ReadUInt8(out byte value)
		{
			value = (byte)(buffer[offset] & 0xFFu);
			offset++;
		}

		internal void ReadUInt32(out uint value)
		{
			value = (buffer[offset] & 0xFFu) | (uint)(buffer[offset + 1] << 8) | (uint)(buffer[offset + 2] << 16) | (uint)(buffer[offset + 3] << 24);
			offset += 4;
		}

		internal void ReadUInt64(out ulong value)
		{
			value = ((ulong)buffer[offset] & 0xFFuL) | ((ulong)buffer[offset + 1] << 8) | ((ulong)buffer[offset + 2] << 16) | ((ulong)buffer[offset + 3] << 24) | ((ulong)buffer[offset + 4] << 32) | ((ulong)buffer[offset + 5] << 40) | ((ulong)buffer[offset + 6] << 48) | ((ulong)buffer[offset + 7] << 56);
			offset += 8;
		}

		internal void ReadInt32(int[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				ReadInt32(out values[i]);
			}
		}

		internal void ReadUInt32(uint[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				ReadUInt32(out values[i]);
			}
		}

		internal void ReadBytes(byte[] bytes)
		{
			for (int i = 0; i < bytes.Length; i++)
			{
				bytes[i] = buffer[offset++];
			}
		}

		internal float ReadFloat()
		{
			float result = BitConverter.ToSingle(buffer, offset);
			offset += 4;
			return result;
		}

		internal double ReadDouble()
		{
			double result = BitConverter.ToDouble(buffer, offset);
			offset += 8;
			return result;
		}

		internal decimal ReadDecimal()
		{
			int[] array = new int[4];
			ReadInt32(array);
			return new decimal(array[2], array[3], array[1], array[0] < 0, (byte)((array[0] & 0xFF0000) >> 16));
		}

		internal void ReadBString(out string value)
		{
			ReadUInt16(out var value2);
			value = Encoding.UTF8.GetString(buffer, offset, value2);
			offset += value2;
		}

		internal string ReadBString(int len)
		{
			string @string = Encoding.UTF8.GetString(buffer, offset, len);
			offset += len;
			return @string;
		}

		internal void ReadCString(out string value)
		{
			int i;
			for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i++)
			{
			}
			value = Encoding.UTF8.GetString(buffer, offset, i);
			offset += i + 1;
		}

		internal void SkipCString(out string value)
		{
			int i;
			for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i++)
			{
			}
			offset += i + 1;
			value = null;
		}

		internal void ReadGuid(out Guid guid)
		{
			ReadUInt32(out var value);
			ReadUInt16(out var value2);
			ReadUInt16(out var value3);
			ReadUInt8(out var value4);
			ReadUInt8(out var value5);
			ReadUInt8(out var value6);
			ReadUInt8(out var value7);
			ReadUInt8(out var value8);
			ReadUInt8(out var value9);
			ReadUInt8(out var value10);
			ReadUInt8(out var value11);
			guid = new Guid(value, value2, value3, value4, value5, value6, value7, value8, value9, value10, value11);
		}

		internal string ReadString()
		{
			int i;
			for (i = 0; offset + i < buffer.Length && buffer[offset + i] != 0; i += 2)
			{
			}
			string @string = Encoding.Unicode.GetString(buffer, offset, i);
			offset += i + 2;
			return @string;
		}
	}
	internal struct BitSet
	{
		private int size;

		private uint[] words;

		internal bool IsEmpty => size == 0;

		internal BitSet(BitAccess bits)
		{
			bits.ReadInt32(out size);
			words = new uint[size];
			bits.ReadUInt32(words);
		}

		internal bool IsSet(int index)
		{
			int num = index / 32;
			if (num >= size)
			{
				return false;
			}
			return (words[num] & GetBit(index)) != 0;
		}

		private static uint GetBit(int index)
		{
			return (uint)(1 << index % 32);
		}
	}
	internal struct FLOAT10
	{
		internal byte Data_0;

		internal byte Data_1;

		internal byte Data_2;

		internal byte Data_3;

		internal byte Data_4;

		internal byte Data_5;

		internal byte Data_6;

		internal byte Data_7;

		internal byte Data_8;

		internal byte Data_9;
	}
	internal enum CV_SIGNATURE
	{
		C6 = 0,
		C7 = 1,
		C11 = 2,
		C13 = 4,
		RESERVERD = 5
	}
	internal enum CV_prmode
	{
		CV_TM_DIRECT = 0,
		CV_TM_NPTR32 = 4,
		CV_TM_NPTR64 = 6,
		CV_TM_NPTR128 = 7
	}
	internal enum CV_type
	{
		CV_SPECIAL = 0,
		CV_SIGNED = 1,
		CV_UNSIGNED = 2,
		CV_BOOLEAN = 3,
		CV_REAL = 4,
		CV_COMPLEX = 5,
		CV_SPECIAL2 = 6,
		CV_INT = 7,
		CV_CVRESERVED = 15
	}
	internal enum CV_special
	{
		CV_SP_NOTYPE,
		CV_SP_ABS,
		CV_SP_SEGMENT,
		CV_SP_VOID,
		CV_SP_CURRENCY,
		CV_SP_NBASICSTR,
		CV_SP_FBASICSTR,
		CV_SP_NOTTRANS,
		CV_SP_HRESULT
	}
	internal enum CV_special2
	{
		CV_S2_BIT,
		CV_S2_PASCHAR
	}
	internal enum CV_integral
	{
		CV_IN_1BYTE,
		CV_IN_2BYTE,
		CV_IN_4BYTE,
		CV_IN_8BYTE,
		CV_IN_16BYTE
	}
	internal enum CV_real
	{
		CV_RC_REAL32,
		CV_RC_REAL64,
		CV_RC_REAL80,
		CV_RC_REAL128
	}
	internal enum CV_int
	{
		CV_RI_CHAR = 0,
		CV_RI_INT1 = 0,
		CV_RI_WCHAR = 1,
		CV_RI_UINT1 = 1,
		CV_RI_INT2 = 2,
		CV_RI_UINT2 = 3,
		CV_RI_INT4 = 4,
		CV_RI_UINT4 = 5,
		CV_RI_INT8 = 6,
		CV_RI_UINT8 = 7,
		CV_RI_INT16 = 8,
		CV_RI_UINT16 = 9
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct CV_PRIMITIVE_TYPE
	{
		private const uint CV_MMASK = 1792u;

		private const uint CV_TMASK = 240u;

		private const uint CV_SMASK = 15u;

		private const int CV_MSHIFT = 8;

		private const int CV_TSHIFT = 4;

		private const int CV_SSHIFT = 0;

		private const uint CV_FIRST_NONPRIM = 4096u;
	}
	internal enum TYPE_ENUM
	{
		T_NOTYPE = 0,
		T_ABS = 1,
		T_SEGMENT = 2,
		T_VOID = 3,
		T_HRESULT = 8,
		T_32PHRESULT = 1032,
		T_64PHRESULT = 1544,
		T_PVOID = 259,
		T_PFVOID = 515,
		T_PHVOID = 771,
		T_32PVOID = 1027,
		T_64PVOID = 1539,
		T_CURRENCY = 4,
		T_NOTTRANS = 7,
		T_BIT = 96,
		T_PASCHAR = 97,
		T_CHAR = 16,
		T_32PCHAR = 1040,
		T_64PCHAR = 1552,
		T_UCHAR = 32,
		T_32PUCHAR = 1056,
		T_64PUCHAR = 1568,
		T_RCHAR = 112,
		T_32PRCHAR = 1136,
		T_64PRCHAR = 1648,
		T_WCHAR = 113,
		T_32PWCHAR = 1137,
		T_64PWCHAR = 1649,
		T_INT1 = 104,
		T_32PINT1 = 1128,
		T_64PINT1 = 1640,
		T_UINT1 = 105,
		T_32PUINT1 = 1129,
		T_64PUINT1 = 1641,
		T_SHORT = 17,
		T_32PSHORT = 1041,
		T_64PSHORT = 1553,
		T_USHORT = 33,
		T_32PUSHORT = 1057,
		T_64PUSHORT = 1569,
		T_INT2 = 114,
		T_32PINT2 = 1138,
		T_64PINT2 = 1650,
		T_UINT2 = 115,
		T_32PUINT2 = 1139,
		T_64PUINT2 = 1651,
		T_LONG = 18,
		T_ULONG = 34,
		T_32PLONG = 1042,
		T_32PULONG = 1058,
		T_64PLONG = 1554,
		T_64PULONG = 1570,
		T_INT4 = 116,
		T_32PINT4 = 1140,
		T_64PINT4 = 1652,
		T_UINT4 = 117,
		T_32PUINT4 = 1141,
		T_64PUINT4 = 1653,
		T_QUAD = 19,
		T_32PQUAD = 1043,
		T_64PQUAD = 1555,
		T_UQUAD = 35,
		T_32PUQUAD = 1059,
		T_64PUQUAD = 1571,
		T_INT8 = 118,
		T_32PINT8 = 1142,
		T_64PINT8 = 1654,
		T_UINT8 = 119,
		T_32PUINT8 = 1143,
		T_64PUINT8 = 1655,
		T_OCT = 20,
		T_32POCT = 1044,
		T_64POCT = 1556,
		T_UOCT = 36,
		T_32PUOCT = 1060,
		T_64PUOCT = 1572,
		T_INT16 = 120,
		T_32PINT16 = 1144,
		T_64PINT16 = 1656,
		T_UINT16 = 121,
		T_32PUINT16 = 1145,
		T_64PUINT16 = 1657,
		T_REAL32 = 64,
		T_32PREAL32 = 1088,
		T_64PREAL32 = 1600,
		T_REAL64 = 65,
		T_32PREAL64 = 1089,
		T_64PREAL64 = 1601,
		T_REAL80 = 66,
		T_32PREAL80 = 1090,
		T_64PREAL80 = 1602,
		T_REAL128 = 67,
		T_32PREAL128 = 1091,
		T_64PREAL128 = 1603,
		T_CPLX32 = 80,
		T_32PCPLX32 = 1104,
		T_64PCPLX32 = 1616,
		T_CPLX64 = 81,
		T_32PCPLX64 = 1105,
		T_64PCPLX64 = 1617,
		T_CPLX80 = 82,
		T_32PCPLX80 = 1106,
		T_64PCPLX80 = 1618,
		T_CPLX128 = 83,
		T_32PCPLX128 = 1107,
		T_64PCPLX128 = 1619,
		T_BOOL08 = 48,
		T_32PBOOL08 = 1072,
		T_64PBOOL08 = 1584,
		T_BOOL16 = 49,
		T_32PBOOL16 = 1073,
		T_64PBOOL16 = 1585,
		T_BOOL32 = 50,
		T_32PBOOL32 = 1074,
		T_64PBOOL32 = 1586,
		T_BOOL64 = 51,
		T_32PBOOL64 = 1075,
		T_64PBOOL64 = 1587
	}
	internal enum LEAF
	{
		LF_VTSHAPE = 10,
		LF_COBOL1 = 12,
		LF_LABEL = 14,
		LF_NULL = 15,
		LF_NOTTRAN = 16,
		LF_ENDPRECOMP = 20,
		LF_TYPESERVER_ST = 22,
		LF_LIST = 515,
		LF_REFSYM = 524,
		LF_ENUMERATE_ST = 1027,
		LF_TI16_MAX = 4096,
		LF_MODIFIER = 4097,
		LF_POINTER = 4098,
		LF_ARRAY_ST = 4099,
		LF_CLASS_ST = 4100,
		LF_STRUCTURE_ST = 4101,
		LF_UNION_ST = 4102,
		LF_ENUM_ST = 4103,
		LF_PROCEDURE = 4104,
		LF_MFUNCTION = 4105,
		LF_COBOL0 = 4106,
		LF_BARRAY = 4107,
		LF_DIMARRAY_ST = 4108,
		LF_VFTPATH = 4109,
		LF_PRECOMP_ST = 4110,
		LF_OEM = 4111,
		LF_ALIAS_ST = 4112,
		LF_OEM2 = 4113,
		LF_SKIP = 4608,
		LF_ARGLIST = 4609,
		LF_DEFARG_ST = 4610,
		LF_FIELDLIST = 4611,
		LF_DERIVED = 4612,
		LF_BITFIELD = 4613,
		LF_METHODLIST = 4614,
		LF_DIMCONU = 4615,
		LF_DIMCONLU = 4616,
		LF_DIMVARU = 4617,
		LF_DIMVARLU = 4618,
		LF_BCLASS = 5120,
		LF_VBCLASS = 5121,
		LF_IVBCLASS = 5122,
		LF_FRIENDFCN_ST = 5123,
		LF_INDEX = 5124,
		LF_MEMBER_ST = 5125,
		LF_STMEMBER_ST = 5126,
		LF_METHOD_ST = 5127,
		LF_NESTTYPE_ST = 5128,
		LF_VFUNCTAB = 5129,
		LF_FRIENDCLS = 5130,
		LF_ONEMETHOD_ST = 5131,
		LF_VFUNCOFF = 5132,
		LF_NESTTYPEEX_ST = 5133,
		LF_MEMBERMODIFY_ST = 5134,
		LF_MANAGED_ST = 5135,
		LF_ST_MAX = 5376,
		LF_TYPESERVER = 5377,
		LF_ENUMERATE = 5378,
		LF_ARRAY = 5379,
		LF_CLASS = 5380,
		LF_STRUCTURE = 5381,
		LF_UNION = 5382,
		LF_ENUM = 5383,
		LF_DIMARRAY = 5384,
		LF_PRECOMP = 5385,
		LF_ALIAS = 5386,
		LF_DEFARG = 5387,
		LF_FRIENDFCN = 5388,
		LF_MEMBER = 5389,
		LF_STMEMBER = 5390,
		LF_METHOD = 5391,
		LF_NESTTYPE = 5392,
		LF_ONEMETHOD = 5393,
		LF_NESTTYPEEX = 5394,
		LF_MEMBERMODIFY = 5395,
		LF_MANAGED = 5396,
		LF_TYPESERVER2 = 5397,
		LF_NUMERIC = 32768,
		LF_CHAR = 32768,
		LF_SHORT = 32769,
		LF_USHORT = 32770,
		LF_LONG = 32771,
		LF_ULONG = 32772,
		LF_REAL32 = 32773,
		LF_REAL64 = 32774,
		LF_REAL80 = 32775,
		LF_REAL128 = 32776,
		LF_QUADWORD = 32777,
		LF_UQUADWORD = 32778,
		LF_COMPLEX32 = 32780,
		LF_COMPLEX64 = 32781,
		LF_COMPLEX80 = 32782,
		LF_COMPLEX128 = 32783,
		LF_VARSTRING = 32784,
		LF_OCTWORD = 32791,
		LF_UOCTWORD = 32792,
		LF_DECIMAL = 32793,
		LF_DATE = 32794,
		LF_UTF8STRING = 32795,
		LF_PAD0 = 240,
		LF_PAD1 = 241,
		LF_PAD2 = 242,
		LF_PAD3 = 243,
		LF_PAD4 = 244,
		LF_PAD5 = 245,
		LF_PAD6 = 246,
		LF_PAD7 = 247,
		LF_PAD8 = 248,
		LF_PAD9 = 249,
		LF_PAD10 = 250,
		LF_PAD11 = 251,
		LF_PAD12 = 252,
		LF_PAD13 = 253,
		LF_PAD14 = 254,
		LF_PAD15 = 255
	}
	internal enum CV_ptrtype
	{
		CV_PTR_BASE_SEG = 3,
		CV_PTR_BASE_VAL = 4,
		CV_PTR_BASE_SEGVAL = 5,
		CV_PTR_BASE_ADDR = 6,
		CV_PTR_BASE_SEGADDR = 7,
		CV_PTR_BASE_TYPE = 8,
		CV_PTR_BASE_SELF = 9,
		CV_PTR_NEAR32 = 10,
		CV_PTR_64 = 12,
		CV_PTR_UNUSEDPTR = 13
	}
	internal enum CV_ptrmode
	{
		CV_PTR_MODE_PTR,
		CV_PTR_MODE_REF,
		CV_PTR_MODE_PMEM,
		CV_PTR_MODE_PMFUNC,
		CV_PTR_MODE_RESERVED
	}
	internal enum CV_pmtype
	{
		CV_PMTYPE_Undef,
		CV_PMTYPE_D_Single,
		CV_PMTYPE_D_Multiple,
		CV_PMTYPE_D_Virtual,
		CV_PMTYPE_D_General,
		CV_PMTYPE_F_Single,
		CV_PMTYPE_F_Multiple,
		CV_PMTYPE_F_Virtual,
		CV_PMTYPE_F_General
	}
	internal enum CV_methodprop
	{
		CV_MTvanilla,
		CV_MTvirtual,
		CV_MTstatic,
		CV_MTfriend,
		CV_MTintro,
		CV_MTpurevirt,
		CV_MTpureintro
	}
	internal enum CV_VTS_desc
	{
		CV_VTS_near,
		CV_VTS_far,
		CV_VTS_thin,
		CV_VTS_outer,
		CV_VTS_meta,
		CV_VTS_near32,
		CV_VTS_far32,
		CV_VTS_unused
	}
	internal enum CV_LABEL_TYPE
	{
		CV_LABEL_NEAR = 0,
		CV_LABEL_FAR = 4
	}
	[Flags]
	internal enum CV_modifier : ushort
	{
		MOD_const = 1,
		MOD_volatile = 2,
		MOD_unaligned = 4
	}
	[Flags]
	internal enum CV_prop : ushort
	{
		packed = 1,
		ctor = 2,
		ovlops = 4,
		isnested = 8,
		cnested = 0x10,
		opassign = 0x20,
		opcast = 0x40,
		fwdref = 0x80,
		scoped = 0x100
	}
	[Flags]
	internal enum CV_fldattr
	{
		access = 3,
		mprop = 0x1C,
		pseudo = 0x20,
		noinherit = 0x40,
		noconstruct = 0x80,
		compgenx = 0x100
	}
	internal struct TYPTYPE
	{
		internal ushort len;

		internal ushort leaf;
	}
	internal struct CV_PDMR32_NVVFCN
	{
		internal int mdisp;
	}
	internal struct CV_PDMR32_VBASE
	{
		internal int mdisp;

		internal int pdisp;

		internal int vdisp;
	}
	internal struct CV_PMFR32_NVSA
	{
		internal uint off;
	}
	internal struct CV_PMFR32_NVMA
	{
		internal uint off;

		internal int disp;
	}
	internal struct CV_PMFR32_VBASE
	{
		internal uint off;

		internal int mdisp;

		internal int pdisp;

		internal int vdisp;
	}
	internal struct LeafModifier
	{
		internal uint type;

		internal CV_modifier attr;
	}
	[Flags]
	internal enum LeafPointerAttr : uint
	{
		ptrtype = 0x1Fu,
		ptrmode = 0xE0u,
		isflat32 = 0x100u,
		isvolatile = 0x200u,
		isconst = 0x400u,
		isunaligned = 0x800u,
		isrestrict = 0x1000u
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct LeafPointer
	{
		internal struct LeafPointerBody
		{
			internal uint utype;

			internal LeafPointerAttr attr;
		}
	}
	internal struct LeafArray
	{
		internal uint elemtype;

		internal uint idxtype;

		internal byte[] data;

		internal string name;
	}
	internal struct LeafClass
	{
		internal ushort count;

		internal ushort property;

		internal uint field;

		internal uint derived;

		internal uint vshape;

		internal byte[] data;

		internal string name;
	}
	internal struct LeafUnion
	{
		internal ushort count;

		internal ushort property;

		internal uint field;

		internal byte[] data;

		internal string name;
	}
	internal struct LeafAlias
	{
		internal uint utype;

		internal string name;
	}
	internal struct LeafManaged
	{
		internal string name;
	}
	internal struct LeafEnum
	{
		internal ushort count;

		internal ushort property;

		internal uint utype;

		internal uint field;

		internal string name;
	}
	internal struct LeafProc
	{
		internal uint rvtype;

		internal byte calltype;

		internal byte reserved;

		internal ushort parmcount;

		internal uint arglist;
	}
	internal struct LeafMFunc
	{
		internal uint rvtype;

		internal uint classtype;

		internal uint thistype;

		internal byte calltype;

		internal byte reserved;

		internal ushort parmcount;

		internal uint arglist;

		internal int thisadjust;
	}
	internal struct LeafVTShape
	{
		internal ushort count;

		internal byte[] desc;
	}
	internal struct LeafCobol0
	{
		internal uint type;

		internal byte[] data;
	}
	internal struct LeafCobol1
	{
		internal byte[] data;
	}
	internal struct LeafBArray
	{
		internal uint utype;
	}
	internal struct LeafLabel
	{
		internal ushort mode;
	}
	internal struct LeafDimArray
	{
		internal uint utype;

		internal uint diminfo;

		internal string name;
	}
	internal struct LeafVFTPath
	{
		internal uint count;

		internal uint[] bases;
	}
	internal struct LeafPreComp
	{
		internal uint start;

		internal uint count;

		internal uint signature;

		internal string name;
	}
	internal struct LeafEndPreComp
	{
		internal uint signature;
	}
	internal struct LeafOEM
	{
		internal ushort cvOEM;

		internal ushort recOEM;

		internal uint count;

		internal uint[] index;
	}
	internal enum OEM_ID
	{
		OEM_MS_FORTRAN90 = 61584,
		OEM_ODI = 16,
		OEM_THOMSON_SOFTWARE = 21587,
		OEM_ODI_REC_BASELIST = 0
	}
	internal struct LeafOEM2
	{
		internal Guid idOem;

		internal uint count;

		internal uint[] index;
	}
	internal struct LeafTypeServer
	{
		internal uint signature;

		internal uint age;

		internal string name;
	}
	internal struct LeafTypeServer2
	{
		internal Guid sig70;

		internal uint age;

		internal string name;
	}
	internal struct LeafSkip
	{
		internal uint type;

		internal byte[] data;
	}
	internal struct LeafArgList
	{
		internal uint count;

		internal uint[] arg;
	}
	internal struct LeafDerived
	{
		internal uint count;

		internal uint[] drvdcls;
	}
	internal struct LeafDefArg
	{
		internal uint type;

		internal byte[] expr;
	}
	internal struct LeafList
	{
		internal byte[] data;
	}
	internal struct LeafFieldList
	{
		internal char[] data;
	}
	internal struct mlMethod
	{
		internal ushort attr;

		internal ushort pad0;

		internal uint index;

		internal uint[] vbaseoff;
	}
	internal struct LeafMethodList
	{
		internal byte[] mList;
	}
	internal struct LeafBitfield
	{
		internal uint type;

		internal byte length;

		internal byte position;
	}
	internal struct LeafDimCon
	{
		internal uint typ;

		internal ushort rank;

		internal byte[] dim;
	}
	internal struct LeafDimVar
	{
		internal uint rank;

		internal uint typ;

		internal uint[] dim;
	}
	internal struct LeafRefSym
	{
		internal byte[] Sym;
	}
	internal struct LeafChar
	{
		internal sbyte val;
	}
	internal struct LeafShort
	{
		internal short val;
	}
	internal struct LeafUShort
	{
		internal ushort val;
	}
	internal struct LeafLong
	{
		internal int val;
	}
	internal struct LeafULong
	{
		internal uint val;
	}
	internal struct LeafQuad
	{
		internal long val;
	}
	internal struct LeafUQuad
	{
		internal ulong val;
	}
	internal struct LeafOct
	{
		internal ulong val0;

		internal ulong val1;
	}
	internal struct LeafUOct
	{
		internal ulong val0;

		internal ulong val1;
	}
	internal struct LeafReal32
	{
		internal float val;
	}
	internal struct LeafReal64
	{
		internal double val;
	}
	internal struct LeafReal80
	{
		internal FLOAT10 val;
	}
	internal struct LeafReal128
	{
		internal ulong val0;

		internal ulong val1;
	}
	internal struct LeafCmplx32
	{
		internal float val_real;

		internal float val_imag;
	}
	internal struct LeafCmplx64
	{
		internal double val_real;

		internal double val_imag;
	}
	internal struct LeafCmplx80
	{
		internal FLOAT10 val_real;

		internal FLOAT10 val_imag;
	}
	internal struct LeafCmplx128
	{
		internal ulong val0_real;

		internal ulong val1_real;

		internal ulong val0_imag;

		internal ulong val1_imag;
	}
	internal struct LeafVarString
	{
		internal ushort len;

		internal byte[] value;
	}
	internal struct LeafIndex
	{
		internal ushort pad0;

		internal uint index;
	}
	internal struct LeafBClass
	{
		internal ushort attr;

		internal uint index;

		internal byte[] offset;
	}
	internal struct LeafVBClass
	{
		internal ushort attr;

		internal uint index;

		internal uint vbptr;

		internal byte[] vbpoff;
	}
	internal struct LeafFriendCls
	{
		internal ushort pad0;

		internal uint index;
	}
	internal struct LeafFriendFcn
	{
		internal ushort pad0;

		internal uint index;

		internal string name;
	}
	internal struct LeafMember
	{
		internal ushort attr;

		internal uint index;

		internal byte[] offset;

		internal string name;
	}
	internal struct LeafSTMember
	{
		internal ushort attr;

		internal uint index;

		internal string name;
	}
	internal struct LeafVFuncTab
	{
		internal ushort pad0;

		internal uint type;
	}
	internal struct LeafVFuncOff
	{
		internal ushort pad0;

		internal uint type;

		internal int offset;
	}
	internal struct LeafMethod
	{
		internal ushort count;

		internal uint mList;

		internal string name;
	}
	internal struct LeafOneMethod
	{
		internal ushort attr;

		internal uint index;

		internal uint[] vbaseoff;

		internal string name;
	}
	internal struct LeafEnumerate
	{
		internal ushort attr;

		internal byte[] value;

		internal string name;
	}
	internal struct LeafNestType
	{
		internal ushort pad0;

		internal uint index;

		internal string name;
	}
	internal struct LeafNestTypeEx
	{
		internal ushort attr;

		internal uint index;

		internal string name;
	}
	internal struct LeafMemberModify
	{
		internal ushort

BepInEx/core/Mono.Cecil.Rocks.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Mono.Cecil.Cil;
using Mono.Cecil.PE;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("Mono.Cecil")]
[assembly: AssemblyCopyright("Copyright © 2008 - 2018 Jb Evain")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("0.10.4.0")]
[assembly: AssemblyInformationalVersion("0.10.4.0")]
[assembly: AssemblyTitle("Mono.Cecil.Rocks")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyVersion("0.10.4.0")]
namespace Mono.Cecil.Rocks;

public class DocCommentId
{
	private StringBuilder id;

	private DocCommentId()
	{
		id = new StringBuilder();
	}

	private void WriteField(FieldDefinition field)
	{
		WriteDefinition('F', (IMemberDefinition)(object)field);
	}

	private void WriteEvent(EventDefinition @event)
	{
		WriteDefinition('E', (IMemberDefinition)(object)@event);
	}

	private void WriteType(TypeDefinition type)
	{
		id.Append('T').Append(':');
		WriteTypeFullName((TypeReference)(object)type);
	}

	private void WriteMethod(MethodDefinition method)
	{
		WriteDefinition('M', (IMemberDefinition)(object)method);
		if (((MethodReference)method).HasGenericParameters)
		{
			id.Append('`').Append('`');
			id.Append(((MethodReference)method).GenericParameters.Count);
		}
		if (((MethodReference)method).HasParameters)
		{
			WriteParameters((IList<ParameterDefinition>)((MethodReference)method).Parameters);
		}
		if (IsConversionOperator(method))
		{
			WriteReturnType(method);
		}
	}

	private static bool IsConversionOperator(MethodDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (self.IsSpecialName)
		{
			if (!(((MemberReference)self).Name == "op_Explicit"))
			{
				return ((MemberReference)self).Name == "op_Implicit";
			}
			return true;
		}
		return false;
	}

	private void WriteReturnType(MethodDefinition method)
	{
		id.Append('~');
		WriteTypeSignature(((MethodReference)method).ReturnType);
	}

	private void WriteProperty(PropertyDefinition property)
	{
		WriteDefinition('P', (IMemberDefinition)(object)property);
		if (property.HasParameters)
		{
			WriteParameters((IList<ParameterDefinition>)((PropertyReference)property).Parameters);
		}
	}

	private void WriteParameters(IList<ParameterDefinition> parameters)
	{
		id.Append('(');
		WriteList(parameters, delegate(ParameterDefinition p)
		{
			WriteTypeSignature(((ParameterReference)p).ParameterType);
		});
		id.Append(')');
	}

	private void WriteTypeSignature(TypeReference type)
	{
		//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_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected I4, but got Unknown
		//IL_010c: 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_00ae: 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_005e: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected I4, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Expected O, but got Unknown
		MetadataType metadataType = type.MetadataType;
		switch (metadataType - 15)
		{
		default:
			switch (metadataType - 27)
			{
			case 0:
				WriteFunctionPointerTypeSignature((FunctionPointerType)type);
				return;
			case 3:
				id.Append('`').Append('`');
				id.Append(((GenericParameter)type).Position);
				return;
			case 5:
				WriteModiferTypeSignature((IModifierType)(OptionalModifierType)type, '!');
				return;
			case 4:
				WriteModiferTypeSignature((IModifierType)(RequiredModifierType)type, '|');
				return;
			}
			break;
		case 5:
			WriteArrayTypeSignature((ArrayType)type);
			return;
		case 1:
			WriteTypeSignature(((TypeSpecification)(ByReferenceType)type).ElementType);
			id.Append('@');
			return;
		case 6:
			WriteGenericInstanceTypeSignature((GenericInstanceType)type);
			return;
		case 4:
			id.Append('`');
			id.Append(((GenericParameter)type).Position);
			return;
		case 0:
			WriteTypeSignature(((TypeSpecification)(PointerType)type).ElementType);
			id.Append('*');
			return;
		case 2:
		case 3:
			break;
		}
		WriteTypeFullName(type);
	}

	private void WriteGenericInstanceTypeSignature(GenericInstanceType type)
	{
		if (Mixin.IsTypeSpecification(((TypeSpecification)type).ElementType))
		{
			throw new NotSupportedException();
		}
		WriteTypeFullName(((TypeSpecification)type).ElementType, stripGenericArity: true);
		id.Append('{');
		WriteList((IList<TypeReference>)type.GenericArguments, WriteTypeSignature);
		id.Append('}');
	}

	private void WriteList<T>(IList<T> list, Action<T> action)
	{
		for (int i = 0; i < list.Count; i++)
		{
			if (i > 0)
			{
				id.Append(',');
			}
			action(list[i]);
		}
	}

	private void WriteModiferTypeSignature(IModifierType type, char id)
	{
		WriteTypeSignature(type.ElementType);
		this.id.Append(id);
		WriteTypeSignature(type.ModifierType);
	}

	private void WriteFunctionPointerTypeSignature(FunctionPointerType type)
	{
		id.Append("=FUNC:");
		WriteTypeSignature(type.ReturnType);
		if (type.HasParameters)
		{
			WriteParameters((IList<ParameterDefinition>)type.Parameters);
		}
	}

	private void WriteArrayTypeSignature(ArrayType type)
	{
		WriteTypeSignature(((TypeSpecification)type).ElementType);
		if (type.IsVector)
		{
			id.Append("[]");
			return;
		}
		id.Append("[");
		WriteList((IList<ArrayDimension>)type.Dimensions, delegate(ArrayDimension dimension)
		{
			if (((ArrayDimension)(ref dimension)).LowerBound.HasValue)
			{
				id.Append(((ArrayDimension)(ref dimension)).LowerBound.Value);
			}
			id.Append(':');
			if (((ArrayDimension)(ref dimension)).UpperBound.HasValue)
			{
				id.Append(((ArrayDimension)(ref dimension)).UpperBound.Value - (((ArrayDimension)(ref dimension)).LowerBound.GetValueOrDefault() + 1));
			}
		});
		id.Append("]");
	}

	private void WriteDefinition(char id, IMemberDefinition member)
	{
		this.id.Append(id).Append(':');
		WriteTypeFullName((TypeReference)(object)member.DeclaringType);
		this.id.Append('.');
		WriteItemName(member.Name);
	}

	private void WriteTypeFullName(TypeReference type, bool stripGenericArity = false)
	{
		if (((MemberReference)type).DeclaringType != null)
		{
			WriteTypeFullName(((MemberReference)type).DeclaringType);
			id.Append('.');
		}
		if (!string.IsNullOrEmpty(type.Namespace))
		{
			id.Append(type.Namespace);
			id.Append('.');
		}
		string text = ((MemberReference)type).Name;
		if (stripGenericArity)
		{
			int num = text.LastIndexOf('`');
			if (num > 0)
			{
				text = text.Substring(0, num);
			}
		}
		id.Append(text);
	}

	private void WriteItemName(string name)
	{
		id.Append(name.Replace('.', '#').Replace('<', '{').Replace('>', '}'));
	}

	public override string ToString()
	{
		return id.ToString();
	}

	public static string GetDocCommentId(IMemberDefinition member)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Invalid comparison between Unknown and I4
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Invalid comparison between Unknown and I4
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Invalid comparison between Unknown and I4
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Invalid comparison between Unknown and I4
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Expected O, but got Unknown
		if (member == null)
		{
			throw new ArgumentNullException("member");
		}
		DocCommentId docCommentId = new DocCommentId();
		MetadataToken metadataToken = ((IMetadataTokenProvider)member).MetadataToken;
		TokenType tokenType = ((MetadataToken)(ref metadataToken)).TokenType;
		if ((int)tokenType <= 67108864)
		{
			if ((int)tokenType != 33554432)
			{
				if ((int)tokenType != 67108864)
				{
					goto IL_009d;
				}
				docCommentId.WriteField((FieldDefinition)member);
			}
			else
			{
				docCommentId.WriteType((TypeDefinition)member);
			}
		}
		else if ((int)tokenType != 100663296)
		{
			if ((int)tokenType != 335544320)
			{
				if ((int)tokenType != 385875968)
				{
					goto IL_009d;
				}
				docCommentId.WriteProperty((PropertyDefinition)member);
			}
			else
			{
				docCommentId.WriteEvent((EventDefinition)member);
			}
		}
		else
		{
			docCommentId.WriteMethod((MethodDefinition)member);
		}
		return docCommentId.ToString();
		IL_009d:
		throw new NotSupportedException(member.FullName);
	}
}
internal static class Functional
{
	public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
	{
		Func<A, R> g = null;
		g = f((A a) => g(a));
		return g;
	}

	public static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource element)
	{
		if (source == null)
		{
			throw new ArgumentNullException("source");
		}
		return PrependIterator(source, element);
	}

	private static IEnumerable<TSource> PrependIterator<TSource>(IEnumerable<TSource> source, TSource element)
	{
		yield return element;
		foreach (TSource item in source)
		{
			yield return item;
		}
	}
}
public interface IILVisitor
{
	void OnInlineNone(OpCode opcode);

	void OnInlineSByte(OpCode opcode, sbyte value);

	void OnInlineByte(OpCode opcode, byte value);

	void OnInlineInt32(OpCode opcode, int value);

	void OnInlineInt64(OpCode opcode, long value);

	void OnInlineSingle(OpCode opcode, float value);

	void OnInlineDouble(OpCode opcode, double value);

	void OnInlineString(OpCode opcode, string value);

	void OnInlineBranch(OpCode opcode, int offset);

	void OnInlineSwitch(OpCode opcode, int[] offsets);

	void OnInlineVariable(OpCode opcode, VariableDefinition variable);

	void OnInlineArgument(OpCode opcode, ParameterDefinition parameter);

	void OnInlineSignature(OpCode opcode, CallSite callSite);

	void OnInlineType(OpCode opcode, TypeReference type);

	void OnInlineField(OpCode opcode, FieldReference field);

	void OnInlineMethod(OpCode opcode, MethodReference method);
}
public static class ILParser
{
	private class ParseContext
	{
		public CodeReader Code { get; set; }

		public int Position { get; set; }

		public MetadataReader Metadata { get; set; }

		public Collection<VariableDefinition> Variables { get; set; }

		public IILVisitor Visitor { get; set; }
	}

	public static void Parse(MethodDefinition method, IILVisitor visitor)
	{
		if (method == null)
		{
			throw new ArgumentNullException("method");
		}
		if (visitor == null)
		{
			throw new ArgumentNullException("visitor");
		}
		if (!method.HasBody || !((MemberReference)method).HasImage)
		{
			throw new ArgumentException();
		}
		((MemberReference)method).Module.Read<MethodDefinition, bool>(method, (Func<MethodDefinition, MetadataReader, bool>)delegate(MethodDefinition m, MetadataReader _)
		{
			ParseMethod(m, visitor);
			return true;
		});
	}

	private static void ParseMethod(MethodDefinition method, IILVisitor visitor)
	{
		ParseContext parseContext = CreateContext(method, visitor);
		CodeReader code = parseContext.Code;
		byte b = ((BinaryReader)(object)code).ReadByte();
		switch (b & 3)
		{
		case 2:
			ParseCode(b >> 2, parseContext);
			break;
		case 3:
			((BinaryStreamReader)code).Advance(-1);
			ParseFatMethod(parseContext);
			break;
		default:
			throw new NotSupportedException();
		}
		code.MoveBackTo(parseContext.Position);
	}

	private static ParseContext CreateContext(MethodDefinition method, IILVisitor visitor)
	{
		CodeReader val = ((MemberReference)method).Module.Read<MethodDefinition, CodeReader>(method, (Func<MethodDefinition, MetadataReader, CodeReader>)((MethodDefinition _, MetadataReader reader) => reader.code));
		int position = val.MoveTo(method);
		return new ParseContext
		{
			Code = val,
			Position = position,
			Metadata = val.reader,
			Visitor = visitor
		};
	}

	private static void ParseFatMethod(ParseContext context)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		CodeReader code = context.Code;
		((BinaryStreamReader)code).Advance(4);
		int code_size = ((BinaryReader)(object)code).ReadInt32();
		MetadataToken val = code.ReadToken();
		if (val != MetadataToken.Zero)
		{
			context.Variables = (Collection<VariableDefinition>)(object)code.ReadVariables(val);
		}
		ParseCode(code_size, context);
	}

	private static void ParseCode(int code_size, ParseContext context)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Expected I4, but got Unknown
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Invalid comparison between Unknown and I4
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: 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_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Invalid comparison between Unknown and I4
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Invalid comparison between Unknown and I4
		//IL_014a: 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_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Invalid comparison between Unknown and I4
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Invalid comparison between Unknown and I4
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Expected O, but got Unknown
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Invalid comparison between Unknown and I4
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Invalid comparison between Unknown and I4
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Expected O, but got Unknown
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Invalid comparison between Unknown and I4
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Invalid comparison between Unknown and I4
		//IL_02db: 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_02e9: Expected O, but got Unknown
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		CodeReader code = context.Code;
		MetadataReader metadata = context.Metadata;
		IILVisitor visitor = context.Visitor;
		int num = ((BinaryStreamReader)code).Position + code_size;
		while (((BinaryStreamReader)code).Position < num)
		{
			byte b = ((BinaryReader)(object)code).ReadByte();
			OpCode val = ((b != 254) ? OpCodes.OneByteOpCode[b] : OpCodes.TwoBytesOpCode[((BinaryReader)(object)code).ReadByte()]);
			OperandType operandType = ((OpCode)(ref val)).OperandType;
			IMetadataTokenProvider val2;
			switch ((int)operandType)
			{
			case 5:
				visitor.OnInlineNone(val);
				break;
			case 10:
			{
				int num2 = ((BinaryReader)(object)code).ReadInt32();
				int[] array = new int[num2];
				for (int i = 0; i < num2; i++)
				{
					array[i] = ((BinaryReader)(object)code).ReadInt32();
				}
				visitor.OnInlineSwitch(val, array);
				break;
			}
			case 15:
				visitor.OnInlineBranch(val, ((BinaryReader)(object)code).ReadSByte());
				break;
			case 0:
				visitor.OnInlineBranch(val, ((BinaryReader)(object)code).ReadInt32());
				break;
			case 16:
				if (val == OpCodes.Ldc_I4_S)
				{
					visitor.OnInlineSByte(val, ((BinaryReader)(object)code).ReadSByte());
				}
				else
				{
					visitor.OnInlineByte(val, ((BinaryReader)(object)code).ReadByte());
				}
				break;
			case 2:
				visitor.OnInlineInt32(val, ((BinaryReader)(object)code).ReadInt32());
				break;
			case 3:
				visitor.OnInlineInt64(val, ((BinaryReader)(object)code).ReadInt64());
				break;
			case 17:
				visitor.OnInlineSingle(val, ((BinaryReader)(object)code).ReadSingle());
				break;
			case 7:
				visitor.OnInlineDouble(val, ((BinaryReader)(object)code).ReadDouble());
				break;
			case 8:
				visitor.OnInlineSignature(val, code.GetCallSite(code.ReadToken()));
				break;
			case 9:
				visitor.OnInlineString(val, code.GetString(code.ReadToken()));
				break;
			case 19:
				visitor.OnInlineArgument(val, code.GetParameter((int)((BinaryReader)(object)code).ReadByte()));
				break;
			case 14:
				visitor.OnInlineArgument(val, code.GetParameter((int)((BinaryReader)(object)code).ReadInt16()));
				break;
			case 18:
				visitor.OnInlineVariable(val, GetVariable(context, ((BinaryReader)(object)code).ReadByte()));
				break;
			case 13:
				visitor.OnInlineVariable(val, GetVariable(context, ((BinaryReader)(object)code).ReadInt16()));
				break;
			case 1:
			case 4:
			case 11:
			case 12:
				{
					val2 = metadata.LookupToken(code.ReadToken());
					MetadataToken metadataToken = val2.MetadataToken;
					TokenType tokenType = ((MetadataToken)(ref metadataToken)).TokenType;
					if ((int)tokenType <= 67108864)
					{
						if ((int)tokenType != 16777216 && (int)tokenType != 33554432)
						{
							if ((int)tokenType == 67108864)
							{
								visitor.OnInlineField(val, (FieldReference)val2);
							}
							break;
						}
						goto IL_02b8;
					}
					if ((int)tokenType <= 167772160)
					{
						if ((int)tokenType != 100663296)
						{
							if ((int)tokenType != 167772160)
							{
								break;
							}
							FieldReference val3 = (FieldReference)(object)((val2 is FieldReference) ? val2 : null);
							if (val3 != null)
							{
								visitor.OnInlineField(val, val3);
								break;
							}
							MethodReference val4 = (MethodReference)(object)((val2 is MethodReference) ? val2 : null);
							if (val4 != null)
							{
								visitor.OnInlineMethod(val, val4);
								break;
							}
							throw new InvalidOperationException();
						}
					}
					else
					{
						if ((int)tokenType == 452984832)
						{
							goto IL_02b8;
						}
						if ((int)tokenType != 721420288)
						{
							break;
						}
					}
					visitor.OnInlineMethod(val, (MethodReference)val2);
					break;
				}
				IL_02b8:
				visitor.OnInlineType(val, (TypeReference)val2);
				break;
			}
		}
	}

	private static VariableDefinition GetVariable(ParseContext context, int index)
	{
		return context.Variables[index];
	}
}
public static class MethodBodyRocks
{
	public static void SimplifyMacros(this MethodBody self)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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)
		//IL_0126: Expected I4, but got Unknown
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: 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_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0315: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03df: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_040f: Unknown result type (might be due to invalid IL or missing references)
		//IL_041c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0429: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_0443: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_046a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0477: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Invalid comparison between Unknown and I4
		//IL_0484: Unknown result type (might be due to invalid IL or missing references)
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		Enumerator<Instruction> enumerator = self.Instructions.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				Instruction current = enumerator.Current;
				OpCode opCode = current.OpCode;
				if ((int)((OpCode)(ref opCode)).OpCodeType != 1)
				{
					continue;
				}
				opCode = current.OpCode;
				Code code = ((OpCode)(ref opCode)).Code;
				switch (code - 2)
				{
				case 0:
					ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 0));
					continue;
				case 1:
					ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 1));
					continue;
				case 2:
					ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 2));
					continue;
				case 3:
					ExpandMacro(current, OpCodes.Ldarg, Mixin.GetParameter(self, 3));
					continue;
				case 4:
					ExpandMacro(current, OpCodes.Ldloc, self.Variables[0]);
					continue;
				case 5:
					ExpandMacro(current, OpCodes.Ldloc, self.Variables[1]);
					continue;
				case 6:
					ExpandMacro(current, OpCodes.Ldloc, self.Variables[2]);
					continue;
				case 7:
					ExpandMacro(current, OpCodes.Ldloc, self.Variables[3]);
					continue;
				case 8:
					ExpandMacro(current, OpCodes.Stloc, self.Variables[0]);
					continue;
				case 9:
					ExpandMacro(current, OpCodes.Stloc, self.Variables[1]);
					continue;
				case 10:
					ExpandMacro(current, OpCodes.Stloc, self.Variables[2]);
					continue;
				case 11:
					ExpandMacro(current, OpCodes.Stloc, self.Variables[3]);
					continue;
				case 12:
					current.OpCode = OpCodes.Ldarg;
					continue;
				case 13:
					current.OpCode = OpCodes.Ldarga;
					continue;
				case 14:
					current.OpCode = OpCodes.Starg;
					continue;
				case 15:
					current.OpCode = OpCodes.Ldloc;
					continue;
				case 16:
					current.OpCode = OpCodes.Ldloca;
					continue;
				case 17:
					current.OpCode = OpCodes.Stloc;
					continue;
				case 19:
					ExpandMacro(current, OpCodes.Ldc_I4, -1);
					continue;
				case 20:
					ExpandMacro(current, OpCodes.Ldc_I4, 0);
					continue;
				case 21:
					ExpandMacro(current, OpCodes.Ldc_I4, 1);
					continue;
				case 22:
					ExpandMacro(current, OpCodes.Ldc_I4, 2);
					continue;
				case 23:
					ExpandMacro(current, OpCodes.Ldc_I4, 3);
					continue;
				case 24:
					ExpandMacro(current, OpCodes.Ldc_I4, 4);
					continue;
				case 25:
					ExpandMacro(current, OpCodes.Ldc_I4, 5);
					continue;
				case 26:
					ExpandMacro(current, OpCodes.Ldc_I4, 6);
					continue;
				case 27:
					ExpandMacro(current, OpCodes.Ldc_I4, 7);
					continue;
				case 28:
					ExpandMacro(current, OpCodes.Ldc_I4, 8);
					continue;
				case 29:
					ExpandMacro(current, OpCodes.Ldc_I4, (int)(sbyte)current.Operand);
					continue;
				case 40:
					current.OpCode = OpCodes.Br;
					continue;
				case 41:
					current.OpCode = OpCodes.Brfalse;
					continue;
				case 42:
					current.OpCode = OpCodes.Brtrue;
					continue;
				case 43:
					current.OpCode = OpCodes.Beq;
					continue;
				case 44:
					current.OpCode = OpCodes.Bge;
					continue;
				case 45:
					current.OpCode = OpCodes.Bgt;
					continue;
				case 46:
					current.OpCode = OpCodes.Ble;
					continue;
				case 47:
					current.OpCode = OpCodes.Blt;
					continue;
				case 48:
					current.OpCode = OpCodes.Bne_Un;
					continue;
				case 49:
					current.OpCode = OpCodes.Bge_Un;
					continue;
				case 50:
					current.OpCode = OpCodes.Bgt_Un;
					continue;
				case 51:
					current.OpCode = OpCodes.Ble_Un;
					continue;
				case 52:
					current.OpCode = OpCodes.Blt_Un;
					continue;
				case 18:
				case 30:
				case 31:
				case 32:
				case 33:
				case 34:
				case 35:
				case 36:
				case 37:
				case 38:
				case 39:
					continue;
				}
				if ((int)code == 188)
				{
					current.OpCode = OpCodes.Leave;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}

	private static void ExpandMacro(Instruction instruction, OpCode opcode, object operand)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		instruction.OpCode = opcode;
		instruction.Operand = operand;
	}

	private static void MakeMacro(Instruction instruction, OpCode opcode)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		instruction.OpCode = opcode;
		instruction.Operand = null;
	}

	public static void Optimize(this MethodBody self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		self.OptimizeLongs();
		self.OptimizeMacros();
	}

	private static void OptimizeLongs(this MethodBody self)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < self.Instructions.Count; i++)
		{
			Instruction val = self.Instructions[i];
			OpCode opCode = val.OpCode;
			if ((int)((OpCode)(ref opCode)).Code == 33)
			{
				long num = (long)val.Operand;
				if (num < int.MaxValue && num > int.MinValue)
				{
					ExpandMacro(val, OpCodes.Ldc_I4, (int)num);
					self.Instructions.Insert(++i, Instruction.Create(OpCodes.Conv_I8));
				}
			}
		}
	}

	public static void OptimizeMacros(this MethodBody self)
	{
		//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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Invalid comparison between Unknown and I4
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected I4, but got Unknown
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_034e: Unknown result type (might be due to invalid IL or missing references)
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0368: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: 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_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: 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_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: 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)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		MethodDefinition method = self.Method;
		Enumerator<Instruction> enumerator = self.Instructions.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				Instruction current = enumerator.Current;
				OpCode opCode = current.OpCode;
				Code code = ((OpCode)(ref opCode)).Code;
				if ((int)code != 32)
				{
					switch (code - 199)
					{
					case 0:
					{
						int index = ((ParameterReference)(ParameterDefinition)current.Operand).Index;
						if (index == -1 && current.Operand == self.ThisParameter)
						{
							index = 0;
						}
						else if (((MethodReference)method).HasThis)
						{
							index++;
						}
						switch (index)
						{
						case 0:
							MakeMacro(current, OpCodes.Ldarg_0);
							break;
						case 1:
							MakeMacro(current, OpCodes.Ldarg_1);
							break;
						case 2:
							MakeMacro(current, OpCodes.Ldarg_2);
							break;
						case 3:
							MakeMacro(current, OpCodes.Ldarg_3);
							break;
						default:
							if (index < 256)
							{
								ExpandMacro(current, OpCodes.Ldarg_S, current.Operand);
							}
							break;
						}
						break;
					}
					case 3:
					{
						int index = ((VariableReference)(VariableDefinition)current.Operand).Index;
						switch (index)
						{
						case 0:
							MakeMacro(current, OpCodes.Ldloc_0);
							break;
						case 1:
							MakeMacro(current, OpCodes.Ldloc_1);
							break;
						case 2:
							MakeMacro(current, OpCodes.Ldloc_2);
							break;
						case 3:
							MakeMacro(current, OpCodes.Ldloc_3);
							break;
						default:
							if (index < 256)
							{
								ExpandMacro(current, OpCodes.Ldloc_S, current.Operand);
							}
							break;
						}
						break;
					}
					case 5:
					{
						int index = ((VariableReference)(VariableDefinition)current.Operand).Index;
						switch (index)
						{
						case 0:
							MakeMacro(current, OpCodes.Stloc_0);
							break;
						case 1:
							MakeMacro(current, OpCodes.Stloc_1);
							break;
						case 2:
							MakeMacro(current, OpCodes.Stloc_2);
							break;
						case 3:
							MakeMacro(current, OpCodes.Stloc_3);
							break;
						default:
							if (index < 256)
							{
								ExpandMacro(current, OpCodes.Stloc_S, current.Operand);
							}
							break;
						}
						break;
					}
					case 1:
					{
						int index = ((ParameterReference)(ParameterDefinition)current.Operand).Index;
						if (index == -1 && current.Operand == self.ThisParameter)
						{
							index = 0;
						}
						else if (((MethodReference)method).HasThis)
						{
							index++;
						}
						if (index < 256)
						{
							ExpandMacro(current, OpCodes.Ldarga_S, current.Operand);
						}
						break;
					}
					case 4:
						if (((VariableReference)(VariableDefinition)current.Operand).Index < 256)
						{
							ExpandMacro(current, OpCodes.Ldloca_S, current.Operand);
						}
						break;
					}
					continue;
				}
				int num = (int)current.Operand;
				switch (num)
				{
				case -1:
					MakeMacro(current, OpCodes.Ldc_I4_M1);
					continue;
				case 0:
					MakeMacro(current, OpCodes.Ldc_I4_0);
					continue;
				case 1:
					MakeMacro(current, OpCodes.Ldc_I4_1);
					continue;
				case 2:
					MakeMacro(current, OpCodes.Ldc_I4_2);
					continue;
				case 3:
					MakeMacro(current, OpCodes.Ldc_I4_3);
					continue;
				case 4:
					MakeMacro(current, OpCodes.Ldc_I4_4);
					continue;
				case 5:
					MakeMacro(current, OpCodes.Ldc_I4_5);
					continue;
				case 6:
					MakeMacro(current, OpCodes.Ldc_I4_6);
					continue;
				case 7:
					MakeMacro(current, OpCodes.Ldc_I4_7);
					continue;
				case 8:
					MakeMacro(current, OpCodes.Ldc_I4_8);
					continue;
				}
				if (num >= -128 && num < 128)
				{
					ExpandMacro(current, OpCodes.Ldc_I4_S, (sbyte)num);
				}
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
		OptimizeBranches(self);
	}

	private static void OptimizeBranches(MethodBody body)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//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_0025: Unknown result type (might be due to invalid IL or missing references)
		ComputeOffsets(body);
		Enumerator<Instruction> enumerator = body.Instructions.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				Instruction current = enumerator.Current;
				OpCode opCode = current.OpCode;
				if ((int)((OpCode)(ref opCode)).OperandType == 0 && OptimizeBranch(current))
				{
					ComputeOffsets(body);
				}
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}

	private static bool OptimizeBranch(Instruction instruction)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected I4, but got Unknown
		//IL_0092: 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)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: 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_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: 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: Invalid comparison between Unknown and I4
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		int offset = ((Instruction)instruction.Operand).Offset;
		int offset2 = instruction.Offset;
		OpCode opCode = instruction.OpCode;
		int num = offset - (offset2 + ((OpCode)(ref opCode)).Size + 4);
		if (num < -128 || num > 127)
		{
			return false;
		}
		opCode = instruction.OpCode;
		Code code = ((OpCode)(ref opCode)).Code;
		switch (code - 55)
		{
		default:
			if ((int)code == 187)
			{
				instruction.OpCode = OpCodes.Leave_S;
			}
			break;
		case 0:
			instruction.OpCode = OpCodes.Br_S;
			break;
		case 1:
			instruction.OpCode = OpCodes.Brfalse_S;
			break;
		case 2:
			instruction.OpCode = OpCodes.Brtrue_S;
			break;
		case 3:
			instruction.OpCode = OpCodes.Beq_S;
			break;
		case 4:
			instruction.OpCode = OpCodes.Bge_S;
			break;
		case 5:
			instruction.OpCode = OpCodes.Bgt_S;
			break;
		case 6:
			instruction.OpCode = OpCodes.Ble_S;
			break;
		case 7:
			instruction.OpCode = OpCodes.Blt_S;
			break;
		case 8:
			instruction.OpCode = OpCodes.Bne_Un_S;
			break;
		case 9:
			instruction.OpCode = OpCodes.Bge_Un_S;
			break;
		case 10:
			instruction.OpCode = OpCodes.Bgt_Un_S;
			break;
		case 11:
			instruction.OpCode = OpCodes.Ble_Un_S;
			break;
		case 12:
			instruction.OpCode = OpCodes.Blt_Un_S;
			break;
		}
		return true;
	}

	private static void ComputeOffsets(MethodBody body)
	{
		//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)
		int num = 0;
		Enumerator<Instruction> enumerator = body.Instructions.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				Instruction current = enumerator.Current;
				current.Offset = num;
				num += current.GetSize();
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}
}
public static class MethodDefinitionRocks
{
	public static MethodDefinition GetBaseMethod(this MethodDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (!self.IsVirtual)
		{
			return self;
		}
		if (self.IsNewSlot)
		{
			return self;
		}
		for (TypeDefinition val = ResolveBaseType(self.DeclaringType); val != null; val = ResolveBaseType(val))
		{
			MethodDefinition matchingMethod = GetMatchingMethod(val, self);
			if (matchingMethod != null)
			{
				return matchingMethod;
			}
		}
		return self;
	}

	public static MethodDefinition GetOriginalBaseMethod(this MethodDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		while (true)
		{
			MethodDefinition baseMethod = self.GetBaseMethod();
			if (baseMethod == self)
			{
				break;
			}
			self = baseMethod;
		}
		return self;
	}

	private static TypeDefinition ResolveBaseType(TypeDefinition type)
	{
		if (type == null)
		{
			return null;
		}
		TypeReference baseType = type.BaseType;
		if (baseType == null)
		{
			return null;
		}
		return baseType.Resolve();
	}

	private static MethodDefinition GetMatchingMethod(TypeDefinition type, MethodDefinition method)
	{
		return MetadataResolver.GetMethod(type.Methods, (MethodReference)(object)method);
	}
}
public static class ModuleDefinitionRocks
{
	public static IEnumerable<TypeDefinition> GetAllTypes(this ModuleDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		return ((IEnumerable<TypeDefinition>)self.Types).SelectMany(Functional.Y((Func<TypeDefinition, IEnumerable<TypeDefinition>> f) => (TypeDefinition type) => ((IEnumerable<TypeDefinition>)type.NestedTypes).SelectMany(f).Prepend(type)));
	}
}
public static class ParameterReferenceRocks
{
	public static int GetSequence(this ParameterReference self)
	{
		return self.Index + 1;
	}
}
public static class SecurityDeclarationRocks
{
	public static PermissionSet ToPermissionSet(this SecurityDeclaration self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (TryProcessPermissionSetAttribute(self, out var set))
		{
			return set;
		}
		return CreatePermissionSet(self);
	}

	private static bool TryProcessPermissionSetAttribute(SecurityDeclaration declaration, out PermissionSet set)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected I4, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		set = null;
		if (!declaration.HasSecurityAttributes && declaration.SecurityAttributes.Count != 1)
		{
			return false;
		}
		SecurityAttribute val = declaration.SecurityAttributes[0];
		if (!Mixin.IsTypeOf(val.AttributeType, "System.Security.Permissions", "PermissionSetAttribute"))
		{
			return false;
		}
		PermissionSetAttribute val2 = new PermissionSetAttribute((SecurityAction)declaration.Action);
		CustomAttributeNamedArgument val3 = val.Properties[0];
		CustomAttributeArgument argument = ((CustomAttributeNamedArgument)(ref val3)).Argument;
		string text = (string)((CustomAttributeArgument)(ref argument)).Value;
		string name = ((CustomAttributeNamedArgument)(ref val3)).Name;
		if (!(name == "XML"))
		{
			if (!(name == "Name"))
			{
				throw new NotImplementedException(((CustomAttributeNamedArgument)(ref val3)).Name);
			}
			val2.Name = text;
		}
		else
		{
			val2.XML = text;
		}
		set = val2.CreatePermissionSet();
		return true;
	}

	private static PermissionSet CreatePermissionSet(SecurityDeclaration declaration)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		PermissionSet permissionSet = new PermissionSet(PermissionState.None);
		Enumerator<SecurityAttribute> enumerator = declaration.SecurityAttributes.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				SecurityAttribute current = enumerator.Current;
				IPermission perm = CreatePermission(declaration, current);
				permissionSet.AddPermission(perm);
			}
			return permissionSet;
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}

	private static IPermission CreatePermission(SecurityDeclaration declaration, SecurityAttribute attribute)
	{
		SecurityAttribute obj = CreateSecurityAttribute(Type.GetType(((MemberReference)attribute.AttributeType).FullName) ?? throw new ArgumentException("attribute"), declaration) ?? throw new InvalidOperationException();
		CompleteSecurityAttribute(obj, attribute);
		return obj.CreatePermission();
	}

	private static void CompleteSecurityAttribute(SecurityAttribute security_attribute, SecurityAttribute attribute)
	{
		if (attribute.HasFields)
		{
			CompleteSecurityAttributeFields(security_attribute, attribute);
		}
		if (attribute.HasProperties)
		{
			CompleteSecurityAttributeProperties(security_attribute, attribute);
		}
	}

	private static void CompleteSecurityAttributeFields(SecurityAttribute security_attribute, SecurityAttribute attribute)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		Type type = security_attribute.GetType();
		Enumerator<CustomAttributeNamedArgument> enumerator = attribute.Fields.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				CustomAttributeNamedArgument current = enumerator.Current;
				FieldInfo? field = type.GetField(((CustomAttributeNamedArgument)(ref current)).Name);
				CustomAttributeArgument argument = ((CustomAttributeNamedArgument)(ref current)).Argument;
				field.SetValue(security_attribute, ((CustomAttributeArgument)(ref argument)).Value);
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}

	private static void CompleteSecurityAttributeProperties(SecurityAttribute security_attribute, SecurityAttribute attribute)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		Type type = security_attribute.GetType();
		Enumerator<CustomAttributeNamedArgument> enumerator = attribute.Properties.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				CustomAttributeNamedArgument current = enumerator.Current;
				PropertyInfo? property = type.GetProperty(((CustomAttributeNamedArgument)(ref current)).Name);
				CustomAttributeArgument argument = ((CustomAttributeNamedArgument)(ref current)).Argument;
				property.SetValue(security_attribute, ((CustomAttributeArgument)(ref argument)).Value, null);
			}
		}
		finally
		{
			((IDisposable)enumerator).Dispose();
		}
	}

	private static SecurityAttribute CreateSecurityAttribute(Type attribute_type, SecurityDeclaration declaration)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Expected I4, but got Unknown
		try
		{
			return (SecurityAttribute)Activator.CreateInstance(attribute_type, (SecurityAction)declaration.Action);
		}
		catch (MissingMethodException)
		{
			return (SecurityAttribute)Activator.CreateInstance(attribute_type, new object[0]);
		}
	}

	public static SecurityDeclaration ToSecurityDeclaration(this PermissionSet self, SecurityAction action, ModuleDefinition module)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_003d: Expected O, but got Unknown
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (module == null)
		{
			throw new ArgumentNullException("module");
		}
		SecurityDeclaration val = new SecurityDeclaration(action);
		SecurityAttribute val2 = new SecurityAttribute(module.TypeSystem.LookupType("System.Security.Permissions", "PermissionSetAttribute"));
		val2.Properties.Add(new CustomAttributeNamedArgument("XML", new CustomAttributeArgument(module.TypeSystem.String, (object)self.ToXml().ToString())));
		val.SecurityAttributes.Add(val2);
		return val;
	}
}
public static class TypeDefinitionRocks
{
	public static IEnumerable<MethodDefinition> GetConstructors(this TypeDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (!self.HasMethods)
		{
			return Empty<MethodDefinition>.Array;
		}
		return ((IEnumerable<MethodDefinition>)self.Methods).Where((MethodDefinition method) => method.IsConstructor);
	}

	public static MethodDefinition GetStaticConstructor(this TypeDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (!self.HasMethods)
		{
			return null;
		}
		return self.GetConstructors().FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition ctor) => ctor.IsStatic));
	}

	public static IEnumerable<MethodDefinition> GetMethods(this TypeDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (!self.HasMethods)
		{
			return Empty<MethodDefinition>.Array;
		}
		return ((IEnumerable<MethodDefinition>)self.Methods).Where((MethodDefinition method) => !method.IsConstructor);
	}

	public static TypeReference GetEnumUnderlyingType(this TypeDefinition self)
	{
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (!self.IsEnum)
		{
			throw new ArgumentException();
		}
		return Mixin.GetEnumUnderlyingType(self);
	}
}
public static class TypeReferenceRocks
{
	public static ArrayType MakeArrayType(this TypeReference self)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return new ArrayType(self);
	}

	public static ArrayType MakeArrayType(this TypeReference self, int rank)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (rank == 0)
		{
			throw new ArgumentOutOfRangeException("rank");
		}
		ArrayType val = new ArrayType(self);
		for (int i = 1; i < rank; i++)
		{
			val.Dimensions.Add(default(ArrayDimension));
		}
		return val;
	}

	public static PointerType MakePointerType(this TypeReference self)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return new PointerType(self);
	}

	public static ByReferenceType MakeByReferenceType(this TypeReference self)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return new ByReferenceType(self);
	}

	public static OptionalModifierType MakeOptionalModifierType(this TypeReference self, TypeReference modifierType)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		return new OptionalModifierType(modifierType, self);
	}

	public static RequiredModifierType MakeRequiredModifierType(this TypeReference self, TypeReference modifierType)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		return new RequiredModifierType(modifierType, self);
	}

	public static GenericInstanceType MakeGenericInstanceType(this TypeReference self, params TypeReference[] arguments)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		if (self == null)
		{
			throw new ArgumentNullException("self");
		}
		if (arguments == null)
		{
			throw new ArgumentNullException("arguments");
		}
		if (arguments.Length == 0)
		{
			throw new ArgumentException();
		}
		if (self.GenericParameters.Count != arguments.Length)
		{
			throw new ArgumentException();
		}
		GenericInstanceType val = new GenericInstanceType(self);
		foreach (TypeReference val2 in arguments)
		{
			val.GenericArguments.Add(val2);
		}
		return val;
	}

	public static PinnedType MakePinnedType(this TypeReference self)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return new PinnedType(self);
	}

	public static SentinelType MakeSentinelType(this TypeReference self)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return new SentinelType(self);
	}
}

BepInEx/core/MonoMod.RuntimeDetour.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour.HookGen;
using MonoMod.RuntimeDetour.Platforms;
using MonoMod.Utils;
using MonoMod.Utils.Cil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("0x0ade")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2022 0x0ade")]
[assembly: AssemblyDescription("Flexible and easily extensible runtime detouring library. Wrap, replace and manipulate (Mono.Cecil) methods at runtime.")]
[assembly: AssemblyFileVersion("22.1.29.1")]
[assembly: AssemblyInformationalVersion("22.01.29.01")]
[assembly: AssemblyProduct("MonoMod.RuntimeDetour")]
[assembly: AssemblyTitle("MonoMod.RuntimeDetour")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("22.1.29.1")]
[module: UnverifiableCode]
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
	{
	}
}
internal static class MultiTargetShims
{
	private static readonly object[] _NoArgs = new object[0];

	public static string Replace(this string self, string oldValue, string newValue, StringComparison comparison)
	{
		return self.Replace(oldValue, newValue);
	}

	public static bool Contains(this string self, string value, StringComparison comparison)
	{
		return self.Contains(value);
	}

	public static int GetHashCode(this string self, StringComparison comparison)
	{
		return self.GetHashCode();
	}

	public static int IndexOf(this string self, char value, StringComparison comparison)
	{
		return self.IndexOf(value);
	}

	public static int IndexOf(this string self, string value, StringComparison comparison)
	{
		return self.IndexOf(value);
	}

	public static TypeReference GetConstraintType(this TypeReference type)
	{
		return type;
	}
}
namespace MonoMod
{
	internal static class MMDbgLog
	{
		public static readonly string Tag;

		public static TextWriter Writer;

		public static bool Debugging;

		static MMDbgLog()
		{
			Tag = typeof(MMDbgLog).Assembly.GetName().Name;
			if (!(Environment.GetEnvironmentVariable("MONOMOD_DBGLOG") == "1"))
			{
				string? environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_DBGLOG");
				bool? obj;
				if (environmentVariable == null)
				{
					obj = null;
				}
				else
				{
					string text = environmentVariable.ToLower(CultureInfo.InvariantCulture);
					obj = ((text != null) ? new bool?(MultiTargetShims.Contains(text, Tag.ToLower(CultureInfo.InvariantCulture), StringComparison.Ordinal)) : null);
				}
				bool? flag = obj;
				if (!flag.GetValueOrDefault())
				{
					return;
				}
			}
			Start();
		}

		public static void WaitForDebugger()
		{
			if (!Debugging)
			{
				Debugging = true;
				Debugger.Launch();
				Thread.Sleep(6000);
				Debugger.Break();
			}
		}

		public static void Start()
		{
			if (Writer != null)
			{
				return;
			}
			string text = Environment.GetEnvironmentVariable("MONOMOD_DBGLOG_PATH");
			if (text == "-")
			{
				Writer = Console.Out;
				return;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "mmdbglog.txt";
			}
			text = Path.GetFullPath(Path.GetFileNameWithoutExtension(text) + "-" + Tag + Path.GetExtension(text));
			try
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
			catch
			{
			}
			try
			{
				string directoryName = Path.GetDirectoryName(text);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				Writer = new StreamWriter(new FileStream(text, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete), Encoding.UTF8);
			}
			catch
			{
			}
		}

		public static void Log(string str)
		{
			TextWriter writer = Writer;
			if (writer != null)
			{
				writer.WriteLine(str);
				writer.Flush();
			}
		}

		public static T Log<T>(string str, T value)
		{
			TextWriter writer = Writer;
			if (writer == null)
			{
				return value;
			}
			writer.WriteLine(string.Format(CultureInfo.InvariantCulture, str, new object[1] { value }));
			writer.Flush();
			return value;
		}
	}
}
namespace MonoMod.RuntimeDetour
{
	public struct DetourConfig
	{
		public bool ManualApply;

		public int Priority;

		public string ID;

		public IEnumerable<string> Before;

		public IEnumerable<string> After;
	}
	public class Detour : ISortableDetour, IDetour, IDisposable
	{
		private static Dictionary<MethodBase, List<Detour>> _DetourMap = new Dictionary<MethodBase, List<Detour>>((IEqualityComparer<MethodBase>?)new GenericMethodInstantiationComparer());

		private static Dictionary<MethodBase, MethodInfo> _BackupMethods = new Dictionary<MethodBase, MethodInfo>();

		private static uint _GlobalIndexNext = 0u;

		public static Func<Detour, MethodBase, MethodBase, bool> OnDetour;

		public static Func<Detour, bool> OnUndo;

		public static Func<Detour, MethodBase, MethodBase> OnGenerateTrampoline;

		private readonly uint _GlobalIndex;

		private int _Priority;

		private string _ID;

		private List<string> _Before = new List<string>();

		private ReadOnlyCollection<string> _BeforeRO;

		private List<string> _After = new List<string>();

		private ReadOnlyCollection<string> _AfterRO;

		public readonly MethodBase Method;

		public readonly MethodBase Target;

		public readonly MethodBase TargetReal;

		private NativeDetour _TopDetour;

		private MethodInfo _ChainedTrampoline;

		private static int compileMethodSubscribed = 0;

		private List<Detour> _DetourChain
		{
			get
			{
				if (!_DetourMap.TryGetValue(Method, out var value))
				{
					return null;
				}
				return value;
			}
		}

		public bool IsValid => Index != -1;

		public bool IsApplied { get; private set; }

		private bool IsTop => _TopDetour != null;

		public int Index => _DetourChain?.IndexOf(this) ?? (-1);

		public int MaxIndex => _DetourChain?.Count ?? (-1);

		public uint GlobalIndex => _GlobalIndex;

		public int Priority
		{
			get
			{
				return _Priority;
			}
			set
			{
				if (_Priority != value)
				{
					_Priority = value;
					_RefreshChain(Method);
				}
			}
		}

		public string ID
		{
			get
			{
				return _ID;
			}
			set
			{
				if (string.IsNullOrEmpty(value))
				{
					value = Extensions.GetID(Target, (string)null, (string)null, true, false, true);
				}
				if (!(_ID == value))
				{
					_ID = value;
					_RefreshChain(Method);
				}
			}
		}

		public IEnumerable<string> Before
		{
			get
			{
				return _BeforeRO ?? (_BeforeRO = _Before.AsReadOnly());
			}
			set
			{
				lock (_Before)
				{
					_Before.Clear();
					if (value != null)
					{
						foreach (string item in value)
						{
							_Before.Add(item);
						}
					}
					_RefreshChain(Method);
				}
			}
		}

		public IEnumerable<string> After
		{
			get
			{
				return _AfterRO ?? (_AfterRO = _After.AsReadOnly());
			}
			set
			{
				lock (_After)
				{
					_After.Clear();
					if (value != null)
					{
						foreach (string item in value)
						{
							_After.Add(item);
						}
					}
					_RefreshChain(Method);
				}
			}
		}

		public Detour(MethodBase from, MethodBase to, ref DetourConfig config)
		{
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			from = from.GetIdentifiable();
			if (from.Equals(to))
			{
				throw new ArgumentException("Cannot detour a method to itself!");
			}
			MMDbgLog.Log("detour from " + Extensions.GetID(from, (string)null, (string)null, true, false, false) + " to " + Extensions.GetID(to, (string)null, (string)null, true, false, false));
			Method = from;
			Target = to.Pin();
			TargetReal = DetourHelper.Runtime.GetDetourTarget(from, to);
			_GlobalIndex = _GlobalIndexNext++;
			_Priority = config.Priority;
			_ID = config.ID;
			if (config.Before != null)
			{
				foreach (string item in config.Before)
				{
					_Before.Add(item);
				}
			}
			if (config.After != null)
			{
				foreach (string item2 in config.After)
				{
					_After.Add(item2);
				}
			}
			lock (_BackupMethods)
			{
				if ((!_BackupMethods.TryGetValue(Method, out var value) || (object)value == null) && (object)(value = Method.CreateILCopy()) != null)
				{
					_BackupMethods[Method] = value.Pin();
				}
			}
			ParameterInfo[] parameters = Method.GetParameters();
			Type[] array;
			if (!Method.IsStatic)
			{
				array = new Type[parameters.Length + 1];
				array[0] = Extensions.GetThisParamType(Method);
				for (int i = 0; i < parameters.Length; i++)
				{
					array[i + 1] = parameters[i].ParameterType;
				}
			}
			else
			{
				array = new Type[parameters.Length];
				for (int j = 0; j < parameters.Length; j++)
				{
					array[j] = parameters[j].ParameterType;
				}
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition($"Chain<{Extensions.GetID(Method, (string)null, (string)null, true, false, true)}>?{GetHashCode()}", (Method as MethodInfo)?.ReturnType ?? typeof(void), array);
			try
			{
				_ChainedTrampoline = val.StubCriticalDetour().Generate().Pin();
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			List<Detour> value2;
			lock (_DetourMap)
			{
				if (!_DetourMap.TryGetValue(Method, out value2))
				{
					value2 = (_DetourMap[Method] = new List<Detour>());
				}
			}
			lock (value2)
			{
				value2.Add(this);
			}
			if (!config.ManualApply)
			{
				Apply();
			}
		}

		public Detour(MethodBase from, MethodBase to, DetourConfig config)
			: this(from, to, ref config)
		{
		}

		public Detour(MethodBase from, MethodBase to)
			: this(from, to, DetourContext.Current?.DetourConfig ?? default(DetourConfig))
		{
		}

		public Detour(MethodBase method, IntPtr to, ref DetourConfig config)
			: this(method, DetourHelper.GenerateNativeProxy(to, method), ref config)
		{
		}

		public Detour(MethodBase method, IntPtr to, DetourConfig config)
			: this(method, DetourHelper.GenerateNativeProxy(to, method), ref config)
		{
		}

		public Detour(MethodBase method, IntPtr to)
			: this(method, DetourHelper.GenerateNativeProxy(to, method))
		{
		}

		public Detour(Delegate from, IntPtr to, ref DetourConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Detour(Delegate from, IntPtr to, DetourConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Detour(Delegate from, IntPtr to)
			: this(from.Method, to)
		{
		}

		public Detour(Delegate from, Delegate to, ref DetourConfig config)
			: this(from.Method, to.Method, ref config)
		{
		}

		public Detour(Delegate from, Delegate to, DetourConfig config)
			: this(from.Method, to.Method, ref config)
		{
		}

		public Detour(Delegate from, Delegate to)
			: this(from.Method, to.Method)
		{
		}

		public Detour(Expression from, IntPtr to, ref DetourConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Detour(Expression from, IntPtr to, DetourConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Detour(Expression from, IntPtr to)
			: this(((MethodCallExpression)from).Method, to)
		{
		}

		public Detour(Expression from, Expression to, ref DetourConfig config)
			: this(((MethodCallExpression)from).Method, ((MethodCallExpression)to).Method, ref config)
		{
		}

		public Detour(Expression from, Expression to, DetourConfig config)
			: this(((MethodCallExpression)from).Method, ((MethodCallExpression)to).Method, ref config)
		{
		}

		public Detour(Expression from, Expression to)
			: this(((MethodCallExpression)from).Method, ((MethodCallExpression)to).Method)
		{
		}

		public Detour(Expression<Action> from, IntPtr to, ref DetourConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Detour(Expression<Action> from, IntPtr to, DetourConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Detour(Expression<Action> from, IntPtr to)
			: this(from.Body, to)
		{
		}

		public Detour(Expression<Action> from, Expression<Action> to, ref DetourConfig config)
			: this(from.Body, to.Body, ref config)
		{
		}

		public Detour(Expression<Action> from, Expression<Action> to, DetourConfig config)
			: this(from.Body, to.Body, ref config)
		{
		}

		public Detour(Expression<Action> from, Expression<Action> to)
			: this(from.Body, to.Body)
		{
		}

		public void Apply()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("Detour");
			}
			if (!IsApplied)
			{
				Func<Detour, MethodBase, MethodBase, bool> onDetour = OnDetour;
				if (onDetour == null || Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[3] { this, Method, Target }))
				{
					IsApplied = true;
					_RefreshChain(Method);
				}
			}
		}

		public void Undo()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("Detour");
			}
			if (IsApplied)
			{
				Func<Detour, bool> onUndo = OnUndo;
				if (onUndo == null || Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this }))
				{
					IsApplied = false;
					_RefreshChain(Method);
				}
			}
		}

		public void Free()
		{
			if (!IsValid)
			{
				return;
			}
			Undo();
			List<Detour> detourChain = _DetourChain;
			lock (detourChain)
			{
				detourChain.Remove(this);
				if (detourChain.Count == 0)
				{
					lock (_BackupMethods)
					{
						if (_BackupMethods.TryGetValue(Method, out var value))
						{
							value.Unpin();
							_BackupMethods.Remove(Method);
						}
					}
					lock (_DetourMap)
					{
						_DetourMap.Remove(Method);
					}
				}
			}
			_ChainedTrampoline.Unpin();
			Target.Unpin();
		}

		public void Dispose()
		{
			if (IsValid)
			{
				Undo();
				Free();
			}
		}

		public MethodBase GenerateTrampoline(MethodBase signature = null)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			Func<Detour, MethodBase, MethodBase> onGenerateTrampoline = OnGenerateTrampoline;
			MethodBase methodBase = ((onGenerateTrampoline != null) ? Extensions.InvokeWhileNull<MethodBase>((MulticastDelegate)onGenerateTrampoline, new object[2] { this, signature }) : null);
			if ((object)methodBase != null)
			{
				return methodBase;
			}
			if ((object)signature == null)
			{
				signature = Target;
			}
			Type type = (signature as MethodInfo)?.ReturnType ?? typeof(void);
			ParameterInfo[] parameters = signature.GetParameters();
			Type[] array = new Type[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				array[i] = parameters[i].ParameterType;
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition($"Trampoline<{Extensions.GetID(Method, (string)null, (string)null, true, false, true)}>?{GetHashCode()}", type, array);
			try
			{
				ILProcessor iLProcessor = val.GetILProcessor();
				for (int j = 0; j < 32; j++)
				{
					iLProcessor.Emit(OpCodes.Nop);
				}
				for (int k = 0; k < array.Length; k++)
				{
					iLProcessor.Emit(OpCodes.Ldarg, k);
				}
				Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)_ChainedTrampoline);
				iLProcessor.Emit(OpCodes.Ret);
				return val.Generate();
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		public T GenerateTrampoline<T>() where T : Delegate
		{
			if (!typeof(Delegate).IsAssignableFrom(typeof(T)))
			{
				throw new InvalidOperationException($"Type {typeof(T)} not a delegate type.");
			}
			return Extensions.CreateDelegate(GenerateTrampoline(typeof(T).GetMethod("Invoke")), typeof(T)) as T;
		}

		private void _TopUndo()
		{
			if (_TopDetour != null)
			{
				_TopDetour.Undo();
				_TopDetour.Free();
				_TopDetour = null;
				Method.Unpin();
				TargetReal.Unpin();
			}
		}

		private void _TopApply()
		{
			if (_TopDetour == null)
			{
				_TopDetour = new NativeDetour(Method.Pin().GetNativeStart(), TargetReal.Pin().GetNativeStart());
			}
		}

		private static void _OnCompileMethod(MethodBase method, IntPtr codeStart, ulong codeLen)
		{
			if ((object)method == null)
			{
				return;
			}
			MMDbgLog.Log("compiling: " + Extensions.GetID(method, (string)null, (string)null, true, false, false));
			if (_DetourMap.TryGetValue(method, out var value))
			{
				value.FindLast((Detour d) => d.IsTop)?._TopDetour?.ChangeSource(codeStart);
			}
		}

		private static void _RefreshChain(MethodBase method)
		{
			if (Interlocked.CompareExchange(ref compileMethodSubscribed, 1, 0) == 0)
			{
				DetourHelper.Runtime.OnMethodCompiled += _OnCompileMethod;
			}
			MMDbgLog.Log("detours applying for " + Extensions.GetID(method, (string)null, (string)null, true, false, false));
			List<Detour> list = _DetourMap[method];
			lock (list)
			{
				DetourSorter<Detour>.Sort(list);
				Detour detour = list.FindLast((Detour d) => d.IsTop);
				Detour detour2 = list.FindLast((Detour d) => d.IsApplied);
				if (detour != detour2)
				{
					detour?._TopUndo();
				}
				if (list.Count == 0)
				{
					return;
				}
				MethodBase method2 = _BackupMethods[method];
				foreach (Detour item in list)
				{
					if (item.IsApplied)
					{
						_ = item._ChainedTrampoline;
						using (NativeDetour nativeDetour = new NativeDetour(item._ChainedTrampoline.GetNativeStart(), method2.GetNativeStart()))
						{
							nativeDetour.Free();
						}
						method2 = item.Target;
					}
				}
				if (detour != detour2)
				{
					detour2?._TopApply();
				}
			}
		}
	}
	public class Detour<T> : Detour where T : Delegate
	{
		public Detour(T from, IntPtr to, ref DetourConfig config)
			: base(from, to, ref config)
		{
		}

		public Detour(T from, IntPtr to, DetourConfig config)
			: base(from, to, ref config)
		{
		}

		public Detour(T from, IntPtr to)
			: base(from, to)
		{
		}

		public Detour(T from, T to, ref DetourConfig config)
			: base(from, to, ref config)
		{
		}

		public Detour(T from, T to, DetourConfig config)
			: base(from, to, ref config)
		{
		}

		public Detour(T from, T to)
			: base(from, to)
		{
		}
	}
	public sealed class DetourContext : IDisposable
	{
		[ThreadStatic]
		private static List<DetourContext> _Contexts;

		[ThreadStatic]
		private static DetourContext Last;

		private MethodBase Creator;

		public int Priority;

		private readonly string _FallbackID;

		private string _ID;

		public List<string> Before = new List<string>();

		public List<string> After = new List<string>();

		private bool IsDisposed;

		private static List<DetourContext> Contexts => _Contexts ?? (_Contexts = new List<DetourContext>());

		internal static DetourContext Current
		{
			get
			{
				DetourContext last = Last;
				if (last != null && last.IsValid)
				{
					return Last;
				}
				List<DetourContext> contexts = Contexts;
				int num = contexts.Count - 1;
				while (num > -1)
				{
					DetourContext detourContext = contexts[num];
					if (!detourContext.IsValid)
					{
						contexts.RemoveAt(num);
						num--;
						continue;
					}
					return Last = detourContext;
				}
				return null;
			}
		}

		public string ID
		{
			get
			{
				return _ID ?? _FallbackID;
			}
			set
			{
				_ID = (string.IsNullOrEmpty(value) ? null : value);
			}
		}

		public DetourConfig DetourConfig
		{
			get
			{
				DetourConfig result = default(DetourConfig);
				result.Priority = Priority;
				result.ID = ID;
				result.Before = Before;
				result.After = After;
				return result;
			}
		}

		public HookConfig HookConfig
		{
			get
			{
				HookConfig result = default(HookConfig);
				result.Priority = Priority;
				result.ID = ID;
				result.Before = Before;
				result.After = After;
				return result;
			}
		}

		public ILHookConfig ILHookConfig
		{
			get
			{
				ILHookConfig result = default(ILHookConfig);
				result.Priority = Priority;
				result.ID = ID;
				result.Before = Before;
				result.After = After;
				return result;
			}
		}

		internal bool IsValid
		{
			get
			{
				if (IsDisposed)
				{
					return false;
				}
				if ((object)Creator == null)
				{
					return true;
				}
				StackTrace stackTrace = new StackTrace();
				int frameCount = stackTrace.FrameCount;
				for (int i = 0; i < frameCount; i++)
				{
					if ((object)stackTrace.GetFrame(i).GetMethod() == Creator)
					{
						return true;
					}
				}
				return false;
			}
		}

		public DetourContext(int priority, string id)
		{
			StackTrace stackTrace = new StackTrace();
			int frameCount = stackTrace.FrameCount;
			for (int i = 0; i < frameCount; i++)
			{
				MethodBase method = stackTrace.GetFrame(i).GetMethod();
				if ((object)method?.DeclaringType != typeof(DetourContext))
				{
					Creator = method;
					break;
				}
			}
			object obj = Creator?.DeclaringType?.Assembly?.GetName().Name;
			if (obj == null)
			{
				MethodBase creator = Creator;
				obj = (((object)creator != null) ? Extensions.GetID(creator, (string)null, (string)null, true, false, true) : null);
			}
			_FallbackID = (string)obj;
			Last = this;
			Contexts.Add(this);
			Priority = priority;
			ID = id;
		}

		public DetourContext(string id)
			: this(0, id)
		{
		}

		public DetourContext(int priority)
			: this(priority, null)
		{
		}

		public DetourContext()
			: this(0, null)
		{
		}

		public void Dispose()
		{
			if (IsDisposed)
			{
				IsDisposed = true;
				Last = null;
				Contexts.Remove(this);
			}
		}
	}
	public sealed class DetourModManager : IDisposable
	{
		private readonly Dictionary<IDetour, Assembly> DetourOwners = new Dictionary<IDetour, Assembly>();

		private readonly Dictionary<Assembly, List<IDetour>> OwnedDetourLists = new Dictionary<Assembly, List<IDetour>>();

		public HashSet<Assembly> Ignored = new HashSet<Assembly>();

		private bool Disposed;

		private static readonly string[] HookTypeNames = new string[4] { "MonoMod.RuntimeDetour.NativeDetour", "MonoMod.RuntimeDetour.Detour", "MonoMod.RuntimeDetour.Hook", "MonoMod.RuntimeDetour.ILHook" };

		public event Action<Assembly, MethodBase, Manipulator> OnILHook;

		public event Action<Assembly, MethodBase, MethodBase, object> OnHook;

		public event Action<Assembly, MethodBase, MethodBase> OnDetour;

		public event Action<Assembly, MethodBase, IntPtr, IntPtr> OnNativeDetour;

		public DetourModManager()
		{
			Ignored.Add(typeof(DetourModManager).Assembly);
			ILHook.OnDetour = (Func<ILHook, MethodBase, Manipulator, bool>)Delegate.Combine(ILHook.OnDetour, new Func<ILHook, MethodBase, Manipulator, bool>(RegisterILHook));
			ILHook.OnUndo = (Func<ILHook, bool>)Delegate.Combine(ILHook.OnUndo, new Func<ILHook, bool>(UnregisterDetour));
			Hook.OnDetour = (Func<Hook, MethodBase, MethodBase, object, bool>)Delegate.Combine(Hook.OnDetour, new Func<Hook, MethodBase, MethodBase, object, bool>(RegisterHook));
			Hook.OnUndo = (Func<Hook, bool>)Delegate.Combine(Hook.OnUndo, new Func<Hook, bool>(UnregisterDetour));
			Detour.OnDetour = (Func<Detour, MethodBase, MethodBase, bool>)Delegate.Combine(Detour.OnDetour, new Func<Detour, MethodBase, MethodBase, bool>(RegisterDetour));
			Detour.OnUndo = (Func<Detour, bool>)Delegate.Combine(Detour.OnUndo, new Func<Detour, bool>(UnregisterDetour));
			NativeDetour.OnDetour = (Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool>)Delegate.Combine(NativeDetour.OnDetour, new Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool>(RegisterNativeDetour));
			NativeDetour.OnUndo = (Func<NativeDetour, bool>)Delegate.Combine(NativeDetour.OnUndo, new Func<NativeDetour, bool>(UnregisterDetour));
		}

		public void Dispose()
		{
			if (!Disposed)
			{
				Disposed = true;
				OwnedDetourLists.Clear();
				ILHook.OnDetour = (Func<ILHook, MethodBase, Manipulator, bool>)Delegate.Remove(ILHook.OnDetour, new Func<ILHook, MethodBase, Manipulator, bool>(RegisterILHook));
				ILHook.OnUndo = (Func<ILHook, bool>)Delegate.Remove(ILHook.OnUndo, new Func<ILHook, bool>(UnregisterDetour));
				Hook.OnDetour = (Func<Hook, MethodBase, MethodBase, object, bool>)Delegate.Remove(Hook.OnDetour, new Func<Hook, MethodBase, MethodBase, object, bool>(RegisterHook));
				Hook.OnUndo = (Func<Hook, bool>)Delegate.Remove(Hook.OnUndo, new Func<Hook, bool>(UnregisterDetour));
				Detour.OnDetour = (Func<Detour, MethodBase, MethodBase, bool>)Delegate.Remove(Detour.OnDetour, new Func<Detour, MethodBase, MethodBase, bool>(RegisterDetour));
				Detour.OnUndo = (Func<Detour, bool>)Delegate.Remove(Detour.OnUndo, new Func<Detour, bool>(UnregisterDetour));
				NativeDetour.OnDetour = (Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool>)Delegate.Remove(NativeDetour.OnDetour, new Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool>(RegisterNativeDetour));
				NativeDetour.OnUndo = (Func<NativeDetour, bool>)Delegate.Remove(NativeDetour.OnUndo, new Func<NativeDetour, bool>(UnregisterDetour));
			}
		}

		public void Unload(Assembly asm)
		{
			if ((object)asm == null || Ignored.Contains(asm))
			{
				return;
			}
			HookEndpointManager.RemoveAllOwnedBy(asm);
			if (OwnedDetourLists.TryGetValue(asm, out var value))
			{
				IDetour[] array = value.ToArray();
				for (int i = 0; i < array.Length; i++)
				{
					array[i].Dispose();
				}
				if (value.Count > 0)
				{
					throw new Exception("Some detours failed to unregister in " + asm.FullName);
				}
				OwnedDetourLists.Remove(asm);
			}
		}

		internal Assembly GetHookOwner(StackTrace stack = null)
		{
			if (stack == null)
			{
				stack = new StackTrace();
			}
			Assembly assembly = null;
			int frameCount = stack.FrameCount;
			string text = null;
			for (int i = 0; i < frameCount; i++)
			{
				MethodBase method = stack.GetFrame(i).GetMethod();
				if ((object)method?.DeclaringType == null)
				{
					continue;
				}
				string fullName = method.DeclaringType.FullName;
				if (text == null)
				{
					if (HookTypeNames.Contains(fullName))
					{
						text = method.DeclaringType.FullName;
					}
				}
				else if (!(fullName == text))
				{
					assembly = method?.DeclaringType.Assembly;
					break;
				}
			}
			if (Ignored.Contains(assembly))
			{
				return null;
			}
			return assembly;
		}

		internal void TrackDetour(Assembly owner, IDetour detour)
		{
			if (!OwnedDetourLists.TryGetValue(owner, out var value))
			{
				value = (OwnedDetourLists[owner] = new List<IDetour>());
			}
			value.Add(detour);
			DetourOwners[detour] = owner;
		}

		internal bool RegisterILHook(ILHook _detour, MethodBase from, Manipulator manipulator)
		{
			Assembly hookOwner = GetHookOwner();
			if ((object)hookOwner == null)
			{
				return true;
			}
			this.OnILHook?.Invoke(hookOwner, from, manipulator);
			TrackDetour(hookOwner, _detour);
			return true;
		}

		internal bool RegisterHook(Hook _detour, MethodBase from, MethodBase to, object target)
		{
			Assembly hookOwner = GetHookOwner();
			if ((object)hookOwner == null)
			{
				return true;
			}
			this.OnHook?.Invoke(hookOwner, from, to, target);
			TrackDetour(hookOwner, _detour);
			return true;
		}

		internal bool RegisterDetour(Detour _detour, MethodBase from, MethodBase to)
		{
			Assembly hookOwner = GetHookOwner();
			if ((object)hookOwner == null)
			{
				return true;
			}
			this.OnDetour?.Invoke(hookOwner, from, to);
			TrackDetour(hookOwner, _detour);
			return true;
		}

		internal bool RegisterNativeDetour(NativeDetour _detour, MethodBase method, IntPtr from, IntPtr to)
		{
			Assembly hookOwner = GetHookOwner();
			if ((object)hookOwner == null)
			{
				return true;
			}
			this.OnNativeDetour?.Invoke(hookOwner, method, from, to);
			TrackDetour(hookOwner, _detour);
			return true;
		}

		internal bool UnregisterDetour(IDetour _detour)
		{
			if (DetourOwners.TryGetValue(_detour, out var value))
			{
				DetourOwners.Remove(_detour);
				OwnedDetourLists[value].Remove(_detour);
			}
			return true;
		}
	}
	public static class HarmonyDetourBridge
	{
		public enum Type
		{
			Auto,
			Basic,
			AsOriginal,
			Override
		}

		private class DetourToRDAttribute : Attribute
		{
			public string Type { get; }

			public int SkipParams { get; }

			public string Name { get; }

			public DetourToRDAttribute(string type, int skipParams = 0, string name = null)
			{
				Type = type;
				SkipParams = skipParams;
				Name = name;
			}
		}

		private class DetourToHAttribute : Attribute
		{
			public string Type { get; }

			public int SkipParams { get; }

			public string Name { get; }

			public DetourToHAttribute(string type, int skipParams = 0, string name = null)
			{
				Type = type;
				SkipParams = skipParams;
				Name = name;
			}
		}

		private class TranspileAttribute : Attribute
		{
			public string Type { get; }

			public string Name { get; }

			public TranspileAttribute(string type, string name = null)
			{
				Type = type;
				Name = name;
			}
		}

		private class CriticalAttribute : Attribute
		{
		}

		private static Type CurrentType;

		private static Assembly _HarmonyASM;

		private static readonly HashSet<IDisposable> _Detours;

		private static readonly Dictionary<System.Type, MethodInfo> _Emitters;

		[ThreadStatic]
		private static DynamicMethodDefinition _LastWrapperDMD;

		private static Assembly _SharedStateASM;

		private static DetourConfig _DetourConfig;

		public static bool Initialized { get; private set; }

		static HarmonyDetourBridge()
		{
			_Detours = new HashSet<IDisposable>();
			_Emitters = new Dictionary<System.Type, MethodInfo>();
			System.Type typeFromHandle = typeof(OpCode);
			System.Type proxyType = ILGeneratorShim.GetProxyType<CecilILGenerator>();
			MethodInfo[] methods = proxyType.GetMethods();
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != "Emit")
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length == 2 && (object)parameters[0].ParameterType == typeFromHandle)
				{
					System.Type parameterType = parameters[1].ParameterType;
					if (!_Emitters.ContainsKey(parameterType) || (object)methodInfo.DeclaringType == proxyType)
					{
						_Emitters[parameterType] = methodInfo;
					}
				}
			}
		}

		public static bool Init(bool forceLoad = true, Type type = Type.Auto)
		{
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Expected O, but got Unknown
			if ((object)_HarmonyASM == null)
			{
				_HarmonyASM = _FindHarmony();
			}
			if ((object)_HarmonyASM == null && forceLoad)
			{
				_HarmonyASM = Assembly.Load(new AssemblyName
				{
					Name = "0Harmony"
				});
			}
			if ((object)_HarmonyASM == null)
			{
				return false;
			}
			if (Initialized)
			{
				return true;
			}
			Initialized = true;
			if (type == Type.Auto)
			{
				type = Type.AsOriginal;
			}
			DetourConfig detourConfig = default(DetourConfig);
			detourConfig.Priority = type switch
			{
				Type.Override => 536870911, 
				Type.AsOriginal => -536870912, 
				_ => 0, 
			};
			_DetourConfig = detourConfig;
			CurrentType = type;
			try
			{
				MethodInfo[] methods = typeof(HarmonyDetourBridge).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					bool flag = methodInfo.GetCustomAttributes(typeof(CriticalAttribute), inherit: false).Any();
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(DetourToRDAttribute), inherit: false);
					for (int j = 0; j < customAttributes.Length; j++)
					{
						DetourToRDAttribute detourToRDAttribute = (DetourToRDAttribute)customAttributes[j];
						foreach (MethodInfo item in GetHarmonyMethod(methodInfo, detourToRDAttribute.Type, detourToRDAttribute.SkipParams, detourToRDAttribute.Name))
						{
							flag = false;
							_Detours.Add(new Hook(item, methodInfo));
						}
					}
					customAttributes = methodInfo.GetCustomAttributes(typeof(DetourToHAttribute), inherit: false);
					for (int j = 0; j < customAttributes.Length; j++)
					{
						DetourToHAttribute detourToHAttribute = (DetourToHAttribute)customAttributes[j];
						foreach (MethodInfo item2 in GetHarmonyMethod(methodInfo, detourToHAttribute.Type, detourToHAttribute.SkipParams, detourToHAttribute.Name))
						{
							flag = false;
							_Detours.Add(new Detour(methodInfo, item2));
						}
					}
					customAttributes = methodInfo.GetCustomAttributes(typeof(TranspileAttribute), inherit: false);
					for (int j = 0; j < customAttributes.Length; j++)
					{
						TranspileAttribute transpileAttribute = (TranspileAttribute)customAttributes[j];
						foreach (MethodInfo item3 in GetHarmonyMethod(methodInfo, transpileAttribute.Type, -1, transpileAttribute.Name))
						{
							DynamicMethodDefinition val = new DynamicMethodDefinition((MethodBase)item3);
							try
							{
								flag = false;
								ILContext val2 = new ILContext(val.Definition)
								{
									ReferenceBag = (IILReferenceBag)(object)RuntimeILReferenceBag.Instance
								};
								_Detours.Add((IDisposable)val2);
								val2.Invoke(Extensions.CreateDelegate<Manipulator>((MethodBase)methodInfo));
								if (val2.IsReadOnly)
								{
									val2.Dispose();
									_Detours.Remove((IDisposable)val2);
								}
								else
								{
									_Detours.Add(new Detour(item3, val.Generate()));
								}
							}
							finally
							{
								((IDisposable)val)?.Dispose();
							}
						}
					}
					if (flag)
					{
						throw new Exception("Cannot apply HarmonyDetourBridge rule " + methodInfo.Name);
					}
				}
			}
			catch
			{
				_EarlyReset();
				throw;
			}
			return true;
		}

		private static bool _EarlyReset()
		{
			foreach (IDisposable detour in _Detours)
			{
				detour.Dispose();
			}
			_Detours.Clear();
			return false;
		}

		public static void Reset()
		{
			if (Initialized)
			{
				Initialized = false;
				_EarlyReset();
			}
		}

		private static System.Type GetHarmonyType(string typeName)
		{
			return _HarmonyASM.GetType(typeName) ?? _HarmonyASM.GetType("HarmonyLib." + typeName) ?? _HarmonyASM.GetType("Harmony." + typeName) ?? _HarmonyASM.GetType("Harmony.ILCopying." + typeName);
		}

		private static IEnumerable<MethodInfo> GetHarmonyMethod(MethodInfo ctx, string typeName, int skipParams, string name)
		{
			System.Type harmonyType = GetHarmonyType(typeName);
			if ((object)harmonyType == null)
			{
				return null;
			}
			if (string.IsNullOrEmpty(name))
			{
				name = ctx.Name;
			}
			if (skipParams < 0)
			{
				return from method in harmonyType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					where method.Name == name
					select method;
			}
			return new MethodInfo[1] { harmonyType.GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, (from p in ctx.GetParameters().Skip(skipParams)
				select p.ParameterType).ToArray(), null) };
		}

		private static DynamicMethodDefinition CreateDMD(MethodBase original, string suffix)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			if ((object)original == null)
			{
				throw new ArgumentNullException("original");
			}
			ParameterInfo[] parameters = original.GetParameters();
			System.Type[] array;
			if (!original.IsStatic)
			{
				array = new System.Type[parameters.Length + 1];
				array[0] = Extensions.GetThisParamType(original);
				for (int i = 0; i < parameters.Length; i++)
				{
					array[i + 1] = parameters[i].ParameterType;
				}
			}
			else
			{
				array = new System.Type[parameters.Length];
				for (int j = 0; j < parameters.Length; j++)
				{
					array[j] = parameters[j].ParameterType;
				}
			}
			return new DynamicMethodDefinition(MultiTargetShims.Replace(original.Name + suffix, "<>", "", StringComparison.Ordinal), (original as MethodInfo)?.ReturnType ?? typeof(void), array);
		}

		[DetourToRD("Memory", 0, null)]
		private static long GetMethodStart(MethodBase method, out Exception exception)
		{
			exception = null;
			try
			{
				_Detours.Add((IDisposable)new LazyDisposable<MethodBase>(method, (Action<MethodBase>)delegate(MethodBase m)
				{
					m.Unpin();
				}));
				return (long)method.Pin().GetNativeStart();
			}
			catch (Exception ex)
			{
				exception = ex;
				return 0L;
			}
		}

		[DetourToRD("Memory", 0, null)]
		[Critical]
		private static string WriteJump(long memory, long destination)
		{
			_Detours.Add(new NativeDetour((IntPtr)memory, (IntPtr)destination));
			return null;
		}

		[DetourToRD("Memory", 0, null)]
		[Critical]
		private static string DetourMethod(MethodBase original, MethodBase replacement)
		{
			if ((object)replacement == null)
			{
				replacement = _LastWrapperDMD.Generate();
				_LastWrapperDMD.Dispose();
				_LastWrapperDMD = null;
			}
			_Detours.Add(new Detour(original, replacement, ref _DetourConfig));
			return null;
		}

		[DetourToRD("MethodBodyReader", 1, null)]
		private static MethodInfo EmitMethodForType(object self, System.Type type)
		{
			foreach (KeyValuePair<System.Type, MethodInfo> emitter in _Emitters)
			{
				if ((object)emitter.Key == type)
				{
					return emitter.Value;
				}
			}
			foreach (KeyValuePair<System.Type, MethodInfo> emitter2 in _Emitters)
			{
				if (emitter2.Key.IsAssignableFrom(type))
				{
					return emitter2.Value;
				}
			}
			return null;
		}

		[DetourToRD("PatchProcessor", 2, null)]
		[Critical]
		private static List<DynamicMethod> Patch(Func<object, List<DynamicMethod>> orig, object self)
		{
			orig(self);
			return new List<DynamicMethod>();
		}

		[Transpile("PatchFunctions", null)]
		[Critical]
		private static void UpdateWrapper(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchThrow(i)
			});
			val.Next.OpCode = OpCodes.Pop;
		}

		[Transpile("MethodPatcher", null)]
		[Critical]
		private static void CreatePatchedMethod(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			System.Type t_DynamicTools = GetHarmonyType("DynamicTools");
			if (!val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall(i, t_DynamicTools, "CreateDynamicMethod")
			}))
			{
				il.MakeReadOnly();
				return;
			}
			val.Next.OpCode = OpCodes.Call;
			val.Next.Operand = il.Import((MethodBase)typeof(HarmonyDetourBridge).GetMethod("CreateDMD", BindingFlags.Static | BindingFlags.NonPublic));
			int varDMDi = -1;
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref varDMDi)
			});
			((VariableReference)il.Body.Variables[varDMDi]).VariableType = il.Import(typeof(DynamicMethodDefinition));
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCallvirt<DynamicMethod>(i, "GetILGenerator")
			});
			val.Next.OpCode = OpCodes.Call;
			val.Next.Operand = il.Import((MethodBase)typeof(DynamicMethodDefinition).GetMethod("GetILGenerator", BindingFlags.Instance | BindingFlags.Public));
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall(i, t_DynamicTools, "PrepareDynamicMethod")
			});
			val.Next.OpCode = OpCodes.Pop;
			val.Next.Operand = null;
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, varDMDi)
			});
			int index = val.Index;
			val.Index = index + 1;
			val.EmitDelegate<Func<DynamicMethodDefinition, DynamicMethod>>((Func<DynamicMethodDefinition, DynamicMethod>)delegate(DynamicMethodDefinition dmd)
			{
				_LastWrapperDMD = dmd;
				return null;
			});
		}

		[DetourToRD("HarmonySharedState", 1, null)]
		private static Assembly SharedStateAssembly(Func<Assembly> orig)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_006e: 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_0085: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			Assembly assembly = orig();
			if ((object)assembly != null)
			{
				return assembly;
			}
			if ((object)_SharedStateASM != null)
			{
				return _SharedStateASM;
			}
			string text = (string)GetHarmonyType("HarmonySharedState").GetField("name", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
			ModuleDefinition val = ModuleDefinition.CreateModule("MonoMod.RuntimeDetour." + text, new ModuleParameters
			{
				Kind = (ModuleKind)0,
				ReflectionImporterProvider = MMReflectionImporter.Provider
			});
			try
			{
				TypeDefinition val2 = new TypeDefinition("", text, (TypeAttributes)385)
				{
					BaseType = val.TypeSystem.Object
				};
				val.Types.Add(val2);
				val2.Fields.Add(new FieldDefinition("state", (FieldAttributes)22, val.ImportReference(typeof(Dictionary<MethodBase, byte[]>))));
				val2.Fields.Add(new FieldDefinition("version", (FieldAttributes)22, val.ImportReference(typeof(int))));
				return _SharedStateASM = ReflectionHelper.Load(val);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private static Assembly _FindHarmony()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (assembly.GetName().Name == "0Harmony" || assembly.GetName().Name == "Harmony" || (object)assembly.GetType("Harmony.HarmonyInstance") != null || (object)assembly.GetType("HarmonyLib.Harmony") != null)
				{
					return assembly;
				}
			}
			object obj = System.Type.GetType("Harmony.HarmonyInstance", throwOnError: false, ignoreCase: false)?.Assembly;
			if (obj == null)
			{
				System.Type? type = System.Type.GetType("HarmonyLib.Harmony", throwOnError: false, ignoreCase: false);
				if ((object)type == null)
				{
					return null;
				}
				obj = type.Assembly;
			}
			return (Assembly)obj;
		}
	}
	public struct HookConfig
	{
		public bool ManualApply;

		public int Priority;

		public string ID;

		public IEnumerable<string> Before;

		public IEnumerable<string> After;
	}
	public class Hook : IDetour, IDisposable
	{
		public static Func<Hook, MethodBase, MethodBase, object, bool> OnDetour;

		public static Func<Hook, bool> OnUndo;

		public static Func<Hook, MethodBase, MethodBase> OnGenerateTrampoline;

		public readonly MethodBase Method;

		public readonly MethodBase Target;

		public readonly MethodBase TargetReal;

		public readonly object DelegateTarget;

		private Detour _Detour;

		private readonly Type _OrigDelegateType;

		private readonly MethodInfo _OrigDelegateInvoke;

		private int? _RefTarget;

		private int? _RefTrampoline;

		private int? _RefTrampolineTmp;

		public bool IsValid => _Detour.IsValid;

		public bool IsApplied => _Detour.IsApplied;

		public Detour Detour => _Detour;

		public Hook(MethodBase from, MethodInfo to, object target, ref HookConfig config)
		{
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_025b: Expected O, but got Unknown
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Expected O, but got Unknown
			//IL_0379: Expected O, but got Unknown
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			from = from.GetIdentifiable();
			Method = from;
			Target = to;
			DelegateTarget = target;
			Type type = (from as MethodInfo)?.ReturnType ?? typeof(void);
			if ((object)to.ReturnType != type && !Extensions.IsCompatible(to.ReturnType, type))
			{
				throw new InvalidOperationException($"Return type of hook for {from} doesn't match, must be {((from as MethodInfo)?.ReturnType ?? typeof(void)).FullName}");
			}
			if (target == null && !to.IsStatic)
			{
				throw new InvalidOperationException($"Hook for method {from} must be static, or you must pass a target instance.");
			}
			ParameterInfo[] parameters = Target.GetParameters();
			ParameterInfo[] parameters2 = Method.GetParameters();
			Type[] array;
			if (!Method.IsStatic)
			{
				array = new Type[parameters2.Length + 1];
				array[0] = Extensions.GetThisParamType(Method);
				for (int i = 0; i < parameters2.Length; i++)
				{
					array[i + 1] = parameters2[i].ParameterType;
				}
			}
			else
			{
				array = new Type[parameters2.Length];
				for (int j = 0; j < parameters2.Length; j++)
				{
					array[j] = parameters2[j].ParameterType;
				}
			}
			Type type2 = null;
			if (parameters.Length == array.Length + 1 && typeof(Delegate).IsAssignableFrom(parameters[0].ParameterType))
			{
				type2 = (_OrigDelegateType = parameters[0].ParameterType);
			}
			else if (parameters.Length != array.Length)
			{
				throw new InvalidOperationException($"Parameter count of hook for {from} doesn't match, must be {array.Length}");
			}
			for (int k = 0; k < array.Length; k++)
			{
				Type type3 = array[k];
				Type parameterType = parameters[k + (((object)type2 != null) ? 1 : 0)].ParameterType;
				if (!Extensions.IsCompatible(type3, parameterType))
				{
					throw new InvalidOperationException($"Parameter #{k} of hook for {from} doesn't match, must be {type3.FullName} or related");
				}
			}
			MethodInfo methodInfo = (_OrigDelegateInvoke = type2?.GetMethod("Invoke"));
			DynamicMethodDefinition val = new DynamicMethodDefinition($"Hook<{Extensions.GetID(Method, (string)null, (string)null, true, false, true)}>?{GetHashCode()}", (Method as MethodInfo)?.ReturnType ?? typeof(void), array);
			DynamicMethodDefinition val2 = val;
			DynamicMethodDefinition val3 = val;
			try
			{
				ILProcessor iLProcessor = val2.GetILProcessor();
				if (target != null)
				{
					_RefTarget = DynamicMethodHelper.EmitReference<object>(iLProcessor, target);
				}
				if ((object)type2 != null)
				{
					_RefTrampoline = DynamicMethodHelper.EmitReference<Delegate>(iLProcessor, (Delegate)null);
				}
				for (int l = 0; l < array.Length; l++)
				{
					iLProcessor.Emit(OpCodes.Ldarg, l);
				}
				Extensions.Emit(iLProcessor, OpCodes.Call, Target);
				iLProcessor.Emit(OpCodes.Ret);
				TargetReal = val2.Generate().Pin();
			}
			finally
			{
				((IDisposable)val3)?.Dispose();
			}
			if ((object)type2 != null)
			{
				ParameterInfo[] parameters3 = methodInfo.GetParameters();
				Type[] array2 = new Type[parameters3.Length];
				for (int m = 0; m < parameters3.Length; m++)
				{
					array2[m] = parameters3[m].ParameterType;
				}
				DynamicMethodDefinition val4 = new DynamicMethodDefinition($"Chain:TMP<{Extensions.GetID(Method, (string)null, (string)null, true, false, true)}>?{GetHashCode()}", methodInfo?.ReturnType ?? typeof(void), array2);
				val2 = val4;
				val3 = val4;
				try
				{
					ILProcessor iLProcessor = val2.GetILProcessor();
					_RefTrampolineTmp = DynamicMethodHelper.EmitReference<Delegate>(iLProcessor, (Delegate)null);
					iLProcessor.Emit(OpCodes.Brfalse, iLProcessor.Body.Instructions[0]);
					DynamicMethodHelper.EmitGetReference<Delegate>(iLProcessor, _RefTrampolineTmp.Value);
					for (int n = 0; n < array.Length; n++)
					{
						iLProcessor.Emit(OpCodes.Ldarg, n);
					}
					Extensions.Emit(iLProcessor, OpCodes.Callvirt, (MethodBase)methodInfo);
					iLProcessor.Emit(OpCodes.Ret);
					DynamicMethodHelper.SetReference(_RefTrampoline.Value, (object)Extensions.CreateDelegate((MethodBase)val2.Generate(), type2));
				}
				finally
				{
					((IDisposable)val3)?.Dispose();
				}
			}
			_Detour = new Detour(Method, TargetReal, new DetourConfig
			{
				ManualApply = true,
				Priority = config.Priority,
				ID = config.ID,
				Before = config.Before,
				After = config.After
			});
			_UpdateOrig(null);
			if (!config.ManualApply)
			{
				Apply();
			}
		}

		public Hook(MethodBase from, MethodInfo to, object target, HookConfig config)
			: this(from, to, target, ref config)
		{
		}

		public Hook(MethodBase from, MethodInfo to, object target)
			: this(from, to, target, DetourContext.Current?.HookConfig ?? default(HookConfig))
		{
		}

		public Hook(MethodBase from, MethodInfo to, ref HookConfig config)
			: this(from, to, null, ref config)
		{
		}

		public Hook(MethodBase from, MethodInfo to, HookConfig config)
			: this(from, to, null, ref config)
		{
		}

		public Hook(MethodBase from, MethodInfo to)
			: this(from, to, null)
		{
		}

		public Hook(MethodBase method, IntPtr to, ref HookConfig config)
			: this(method, DetourHelper.GenerateNativeProxy(to, method), null, ref config)
		{
		}

		public Hook(MethodBase method, IntPtr to, HookConfig config)
			: this(method, DetourHelper.GenerateNativeProxy(to, method), null, ref config)
		{
		}

		public Hook(MethodBase method, IntPtr to)
			: this(method, DetourHelper.GenerateNativeProxy(to, method), null)
		{
		}

		public Hook(MethodBase method, Delegate to, ref HookConfig config)
			: this(method, to.Method, to.Target, ref config)
		{
		}

		public Hook(MethodBase method, Delegate to, HookConfig config)
			: this(method, to.Method, to.Target, ref config)
		{
		}

		public Hook(MethodBase method, Delegate to)
			: this(method, to.Method, to.Target)
		{
		}

		public Hook(Delegate from, IntPtr to, ref HookConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Hook(Delegate from, IntPtr to, HookConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Hook(Delegate from, IntPtr to)
			: this(from.Method, to)
		{
		}

		public Hook(Delegate from, Delegate to, ref HookConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Hook(Delegate from, Delegate to, HookConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public Hook(Delegate from, Delegate to)
			: this(from.Method, to)
		{
		}

		public Hook(Expression from, IntPtr to, ref HookConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Hook(Expression from, IntPtr to, HookConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Hook(Expression from, IntPtr to)
			: this(((MethodCallExpression)from).Method, to)
		{
		}

		public Hook(Expression from, Delegate to, ref HookConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Hook(Expression from, Delegate to, HookConfig config)
			: this(((MethodCallExpression)from).Method, to, ref config)
		{
		}

		public Hook(Expression from, Delegate to)
			: this(((MethodCallExpression)from).Method, to)
		{
		}

		public Hook(Expression<Action> from, IntPtr to, ref HookConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Action> from, IntPtr to, HookConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Action> from, IntPtr to)
			: this(from.Body, to)
		{
		}

		public Hook(Expression<Action> from, Delegate to, ref HookConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Action> from, Delegate to, HookConfig config)
			: this(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Action> from, Delegate to)
			: this(from.Body, to)
		{
		}

		public void Apply()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("Hook");
			}
			if (!IsApplied)
			{
				Func<Hook, MethodBase, MethodBase, object, bool> onDetour = OnDetour;
				if (onDetour != null && !Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[4] { this, Method, Target, DelegateTarget }))
				{
					return;
				}
			}
			_Detour.Apply();
		}

		public void Undo()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("Hook");
			}
			if (IsApplied)
			{
				Func<Hook, bool> onUndo = OnUndo;
				if (onUndo != null && !Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this }))
				{
					return;
				}
			}
			_Detour.Undo();
			if (!IsValid)
			{
				_Free();
			}
		}

		public void Free()
		{
			if (IsValid)
			{
				_Detour.Free();
				_Free();
			}
		}

		public void Dispose()
		{
			if (IsValid)
			{
				Undo();
				Free();
			}
		}

		private void _Free()
		{
			if (_RefTarget.HasValue)
			{
				DynamicMethodHelper.FreeReference(_RefTarget.Value);
			}
			if (_RefTrampoline.HasValue)
			{
				DynamicMethodHelper.FreeReference(_RefTrampoline.Value);
			}
			if (_RefTrampolineTmp.HasValue)
			{
				DynamicMethodHelper.FreeReference(_RefTrampolineTmp.Value);
			}
			TargetReal.Unpin();
		}

		public MethodBase GenerateTrampoline(MethodBase signature = null)
		{
			Func<Hook, MethodBase, MethodBase> onGenerateTrampoline = OnGenerateTrampoline;
			MethodBase methodBase = ((onGenerateTrampoline != null) ? Extensions.InvokeWhileNull<MethodBase>((MulticastDelegate)onGenerateTrampoline, new object[2] { this, signature }) : null);
			if ((object)methodBase != null)
			{
				return methodBase;
			}
			return _Detour.GenerateTrampoline(signature);
		}

		public T GenerateTrampoline<T>() where T : Delegate
		{
			if (!typeof(Delegate).IsAssignableFrom(typeof(T)))
			{
				throw new InvalidOperationException($"Type {typeof(T)} not a delegate type.");
			}
			return Extensions.CreateDelegate(GenerateTrampoline(typeof(T).GetMethod("Invoke")), typeof(T)) as T;
		}

		internal void _UpdateOrig(MethodBase invoke)
		{
			if ((object)_OrigDelegateType != null)
			{
				Delegate @delegate = Extensions.CreateDelegate(invoke ?? GenerateTrampoline(_OrigDelegateInvoke), _OrigDelegateType);
				DynamicMethodHelper.SetReference(_RefTrampoline.Value, (object)@delegate);
				DynamicMethodHelper.SetReference(_RefTrampolineTmp.Value, (object)@delegate);
			}
		}
	}
	public class Hook<T> : Hook
	{
		public Hook(Expression<Action> from, T to, ref HookConfig config)
			: base(from.Body, to as Delegate, ref config)
		{
		}

		public Hook(Expression<Action> from, T to, HookConfig config)
			: base(from.Body, to as Delegate, ref config)
		{
		}

		public Hook(Expression<Action> from, T to)
			: base(from.Body, to as Delegate)
		{
		}

		public Hook(Expression<Func<T>> from, IntPtr to, ref HookConfig config)
			: base(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Func<T>> from, IntPtr to, HookConfig config)
			: base(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Func<T>> from, IntPtr to)
			: base(from.Body, to)
		{
		}

		public Hook(Expression<Func<T>> from, Delegate to, ref HookConfig config)
			: base(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Func<T>> from, Delegate to, HookConfig config)
			: base(from.Body, to, ref config)
		{
		}

		public Hook(Expression<Func<T>> from, Delegate to)
			: base(from.Body, to)
		{
		}

		public Hook(T from, IntPtr to, ref HookConfig config)
			: base(from as Delegate, to, ref config)
		{
		}

		public Hook(T from, IntPtr to, HookConfig config)
			: base(from as Delegate, to, ref config)
		{
		}

		public Hook(T from, IntPtr to)
			: base(from as Delegate, to)
		{
		}

		public Hook(T from, T to, ref HookConfig config)
			: base(from as Delegate, to as Delegate, ref config)
		{
		}

		public Hook(T from, T to, HookConfig config)
			: base(from as Delegate, to as Delegate, ref config)
		{
		}

		public Hook(T from, T to)
			: base(from as Delegate, to as Delegate)
		{
		}
	}
	public class Hook<TFrom, TTo> : Hook
	{
		public Hook(Expression<Func<TFrom>> from, TTo to, ref HookConfig config)
			: base(from.Body, to as Delegate)
		{
		}

		public Hook(Expression<Func<TFrom>> from, TTo to, HookConfig config)
			: base(from.Body, to as Delegate)
		{
		}

		public Hook(Expression<Func<TFrom>> from, TTo to)
			: base(from.Body, to as Delegate)
		{
		}

		public Hook(TFrom from, TTo to, ref HookConfig config)
			: base(from as Delegate, to as Delegate)
		{
		}

		public Hook(TFrom from, TTo to, HookConfig config)
			: base(from as Delegate, to as Delegate)
		{
		}

		public Hook(TFrom from, TTo to)
			: base(from as Delegate, to as Delegate)
		{
		}
	}
	public interface IDetour : IDisposable
	{
		bool IsValid { get; }

		bool IsApplied { get; }

		void Apply();

		void Undo();

		void Free();

		MethodBase GenerateTrampoline(MethodBase signature = null);

		T GenerateTrampoline<T>() where T : Delegate;
	}
	public interface ISortableDetour : IDetour, IDisposable
	{
		uint GlobalIndex { get; }

		int Priority { get; set; }

		string ID { get; set; }

		IEnumerable<string> Before { get; set; }

		IEnumerable<string> After { get; set; }
	}
	public struct ILHookConfig
	{
		public bool ManualApply;

		public int Priority;

		public string ID;

		public IEnumerable<string> Before;

		public IEnumerable<string> After;
	}
	public class ILHook : ISortableDetour, IDetour, IDisposable
	{
		private class Context
		{
			public List<ILHook> Chain = new List<ILHook>();

			public HashSet<ILContext> Active = new HashSet<ILContext>();

			public MethodBase Method;

			public Detour Detour;

			public Context(MethodBase method)
			{
				Method = method;
			}

			public void Add(ILHook hook)
			{
				List<ILHook> chain = Chain;
				lock (chain)
				{
					chain.Add(hook);
				}
			}

			public void Remove(ILHook hook)
			{
				List<ILHook> chain = Chain;
				lock (chain)
				{
					chain.Remove(hook);
					if (chain.Count == 0)
					{
						Refresh();
						lock (_Map)
						{
							_Map.Remove(Method);
							return;
						}
					}
				}
			}

			public void Refresh()
			{
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Expected O, but got Unknown
				List<ILHook> chain = Chain;
				lock (chain)
				{
					foreach (ILContext item in Active)
					{
						item.Dispose();
					}
					Active.Clear();
					Detour?.Dispose();
					Detour = null;
					if (chain.Count == 0)
					{
						return;
					}
					bool flag = false;
					foreach (ILHook item2 in chain)
					{
						if (item2.IsApplied)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						return;
					}
					DetourSorter<ILHook>.Sort(chain);
					DynamicMethodDefinition val = new DynamicMethodDefinition(Method);
					MethodBase to;
					try
					{
						MethodDefinition definition = val.Definition;
						foreach (ILHook item3 in chain)
						{
							if (item3.IsApplied)
							{
								InvokeManipulator(definition, item3.Manipulator);
							}
						}
						to = val.Generate();
					}
					finally
					{
						((IDisposable)val)?.Dispose();
					}
					Detour = new Detour(Method, to, ref ILDetourConfig);
				}
			}

			private void InvokeManipulator(MethodDefinition def, Manipulator cb)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILContext val = new ILContext(def);
				val.ReferenceBag = (IILReferenceBag)(object)RuntimeILReferenceBag.Instance;
				val.Invoke(cb);
				if (val.IsReadOnly)
				{
					val.Dispose();
					return;
				}
				val.MakeReadOnly();
				Active.Add(val);
			}
		}

		public static Func<ILHook, MethodBase, Manipulator, bool> OnDetour;

		public static Func<ILHook, bool> OnUndo;

		private static DetourConfig ILDetourConfig = new DetourConfig
		{
			Priority = -268435456,
			Before = new string[1] { "*" }
		};

		private static Dictionary<MethodBase, Context> _Map = new Dictionary<MethodBase, Context>();

		private static uint _GlobalIndexNext = 0u;

		private readonly uint _GlobalIndex;

		private int _Priority;

		private string _ID;

		private List<string> _Before = new List<string>();

		private ReadOnlyCollection<string> _BeforeRO;

		private List<string> _After = new List<string>();

		private ReadOnlyCollection<string> _AfterRO;

		public readonly MethodBase Method;

		public readonly Manipulator Manipulator;

		private Context _Ctx
		{
			get
			{
				if (!_Map.TryGetValue(Method, out var value))
				{
					return null;
				}
				return value;
			}
		}

		public bool IsValid => Index != -1;

		public bool IsApplied { get; private set; }

		public int Index => _Ctx?.Chain.IndexOf(this) ?? (-1);

		public int MaxIndex => _Ctx?.Chain.Count ?? (-1);

		public uint GlobalIndex => _GlobalIndex;

		public int Priority
		{
			get
			{
				return _Priority;
			}
			set
			{
				if (_Priority != value)
				{
					_Priority = value;
					_Ctx.Refresh();
				}
			}
		}

		public string ID
		{
			get
			{
				return _ID;
			}
			set
			{
				if (string.IsNullOrEmpty(value))
				{
					MethodInfo method = ((Delegate)(object)Manipulator).Method;
					value = (((object)method != null) ? Extensions.GetID((MethodBase)method, (string)null, (string)null, true, false, true) : null) ?? GetHashCode().ToString(CultureInfo.InvariantCulture);
				}
				if (!(_ID == value))
				{
					_ID = value;
					_Ctx.Refresh();
				}
			}
		}

		public IEnumerable<string> Before
		{
			get
			{
				return _BeforeRO ?? (_BeforeRO = _Before.AsReadOnly());
			}
			set
			{
				lock (_Before)
				{
					_Before.Clear();
					if (value != null)
					{
						foreach (string item in value)
						{
							_Before.Add(item);
						}
					}
					_Ctx.Refresh();
				}
			}
		}

		public IEnumerable<string> After
		{
			get
			{
				return _AfterRO ?? (_AfterRO = _After.AsReadOnly());
			}
			set
			{
				lock (_After)
				{
					_After.Clear();
					if (value != null)
					{
						foreach (string item in value)
						{
							_After.Add(item);
						}
					}
					_Ctx.Refresh();
				}
			}
		}

		public ILHook(MethodBase from, Manipulator manipulator, ref ILHookConfig config)
		{
			from = from.GetIdentifiable();
			Method = from.Pin();
			Manipulator = manipulator;
			_GlobalIndex = _GlobalIndexNext++;
			_Priority = config.Priority;
			_ID = config.ID;
			if (config.Before != null)
			{
				foreach (string item in config.Before)
				{
					_Before.Add(item);
				}
			}
			if (config.After != null)
			{
				foreach (string item2 in config.After)
				{
					_After.Add(item2);
				}
			}
			Context value;
			lock (_Map)
			{
				if (!_Map.TryGetValue(Method, out value))
				{
					value = (_Map[Method] = new Context(Method));
				}
			}
			lock (value)
			{
				value.Add(this);
			}
			if (!config.ManualApply)
			{
				Apply();
			}
		}

		public ILHook(MethodBase from, Manipulator manipulator, ILHookConfig config)
			: this(from, manipulator, ref config)
		{
		}

		public ILHook(MethodBase from, Manipulator manipulator)
			: this(from, manipulator, DetourContext.Current?.ILHookConfig ?? default(ILHookConfig))
		{
		}

		public void Apply()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("ILHook");
			}
			if (!IsApplied)
			{
				Func<ILHook, MethodBase, Manipulator, bool> onDetour = OnDetour;
				if (onDetour == null || Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[3] { this, Method, Manipulator }))
				{
					IsApplied = true;
					_Ctx.Refresh();
				}
			}
		}

		public void Undo()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("ILHook");
			}
			if (IsApplied)
			{
				Func<ILHook, bool> onUndo = OnUndo;
				if (onUndo == null || Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this }))
				{
					IsApplied = false;
					_Ctx.Refresh();
				}
			}
		}

		public void Free()
		{
			if (IsValid)
			{
				Undo();
				_Ctx.Remove(this);
				Method.Unpin();
			}
		}

		public void Dispose()
		{
			if (IsValid)
			{
				Undo();
				Free();
			}
		}

		public MethodBase GenerateTrampoline(MethodBase signature = null)
		{
			throw new NotSupportedException();
		}

		public T GenerateTrampoline<T>() where T : Delegate
		{
			throw new NotSupportedException();
		}
	}
	public struct NativeDetourConfig
	{
		public bool ManualApply;

		public bool SkipILCopy;
	}
	public class NativeDetour : IDetour, IDisposable
	{
		public static Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool> OnDetour;

		public static Func<NativeDetour, bool> OnUndo;

		public static Func<NativeDetour, MethodBase, MethodBase> OnGenerateTrampoline;

		private NativeDetourData _Data;

		public readonly MethodBase Method;

		private readonly MethodInfo _BackupMethod;

		private readonly IntPtr _BackupNative;

		private HashSet<MethodBase> _Pinned = new HashSet<MethodBase>();

		public bool IsValid { get; private set; }

		public bool IsApplied { get; private set; }

		public NativeDetourData Data => _Data;

		public NativeDetour(MethodBase method, IntPtr from, IntPtr to, ref NativeDetourConfig config)
		{
			if (from == to)
			{
				throw new InvalidOperationException($"Cannot detour from a location to itself! (from: {from:X16} to: {to:X16} method: {method})");
			}
			method = method?.GetIdentifiable();
			Method = method;
			Func<NativeDetour, MethodBase, IntPtr, IntPtr, bool> onDetour = OnDetour;
			if (onDetour == null || Extensions.InvokeWhileTrue((MulticastDelegate)onDetour, new object[4] { this, method, from, to }))
			{
				IsValid = true;
				_Data = DetourHelper.Native.Create(from, to);
				if (!config.SkipILCopy)
				{
					method?.TryCreateILCopy(out _BackupMethod);
				}
				_BackupNative = DetourHelper.Native.MemAlloc(_Data.Size);
				if (!config.ManualApply)
				{
					Apply();
				}
			}
		}

		public NativeDetour(MethodBase method, IntPtr from, IntPtr to, NativeDetourConfig config)
			: this(method, from, to, ref config)
		{
		}

		public NativeDetour(MethodBase method, IntPtr from, IntPtr to)
			: this(method, from, to, default(NativeDetourConfig))
		{
		}

		public NativeDetour(IntPtr from, IntPtr to, ref NativeDetourConfig config)
			: this(null, from, to, ref config)
		{
		}

		public NativeDetour(IntPtr from, IntPtr to, NativeDetourConfig config)
			: this(null, from, to, ref config)
		{
		}

		public NativeDetour(IntPtr from, IntPtr to)
			: this(null, from, to)
		{
		}

		public NativeDetour(MethodBase from, IntPtr to, ref NativeDetourConfig config)
			: this(from, from.Pin().GetNativeStart(), to, ref config)
		{
			_Pinned.Add(from);
		}

		public NativeDetour(MethodBase from, IntPtr to, NativeDetourConfig config)
			: this(from, from.Pin().GetNativeStart(), to, ref config)
		{
			_Pinned.Add(from);
		}

		public NativeDetour(MethodBase from, IntPtr to)
			: this(from, from.Pin().GetNativeStart(), to)
		{
			_Pinned.Add(from);
		}

		public NativeDetour(IntPtr from, MethodBase to, ref NativeDetourConfig config)
			: this(from, to.Pin().GetNativeStart(), ref config)
		{
			_Pinned.Add(to);
		}

		public NativeDetour(IntPtr from, MethodBase to, NativeDetourConfig config)
			: this(from, to.Pin().GetNativeStart(), ref config)
		{
			_Pinned.Add(to);
		}

		public NativeDetour(IntPtr from, MethodBase to)
			: this(from, to.Pin().GetNativeStart())
		{
			_Pinned.Add(to);
		}

		public NativeDetour(MethodBase from, MethodBase to, ref NativeDetourConfig config)
			: this(from.Pin().GetNativeStart(), DetourHelper.Runtime.GetDetourTarget(from, to), ref config)
		{
			_Pinned.Add(from);
		}

		public NativeDetour(MethodBase from, MethodBase to, NativeDetourConfig config)
			: this(from.Pin().GetNativeStart(), DetourHelper.Runtime.GetDetourTarget(from, to), ref config)
		{
			_Pinned.Add(from);
		}

		public NativeDetour(MethodBase from, MethodBase to)
			: this(from.Pin().GetNativeStart(), DetourHelper.Runtime.GetDetourTarget(from, to))
		{
			_Pinned.Add(from);
		}

		public NativeDetour(Delegate from, IntPtr to, ref NativeDetourConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public NativeDetour(Delegate from, IntPtr to, NativeDetourConfig config)
			: this(from.Method, to, ref config)
		{
		}

		public NativeDetour(Delegate from, IntPtr to)
			: this(from.Method, to)
		{
		}

		public NativeDetour(IntPtr from, Delegate to, ref NativeDetourConfig config)
			: this(from, to.Method, ref config)
		{
		}

		public NativeDetour(IntPtr from, Delegate to, NativeDetourConfig config)
			: this(from, to.Method, ref config)
		{
		}

		public NativeDetour(IntPtr from, Delegate to)
			: this(from, to.Method)
		{
		}

		public NativeDetour(Delegate from, Delegate to, ref NativeDetourConfig config)
			: this(from.Method, to.Method, ref config)
		{
		}

		public NativeDetour(Delegate from, Delegate to, NativeDetourConfig config)
			: this(from.Method, to.Method, ref config)
		{
		}

		public NativeDetour(Delegate from, Delegate to)
			: this(from.Method, to.Method)
		{
		}

		public void Apply()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("NativeDetour");
			}
			if (!IsApplied)
			{
				IsApplied = true;
				DetourHelper.Native.Copy(_Data.Method, _BackupNative, _Data.Type);
				DetourHelper.Native.MakeWritable(_Data);
				DetourHelper.Native.Apply(_Data);
				DetourHelper.Native.MakeExecutable(_Data);
				DetourHelper.Native.FlushICache(_Data);
			}
		}

		public void Undo()
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("NativeDetour");
			}
			Func<NativeDetour, bool> onUndo = OnUndo;
			if ((onUndo == null || Extensions.InvokeWhileTrue((MulticastDelegate)onUndo, new object[1] { this })) && IsApplied)
			{
				IsApplied = false;
				DetourHelper.Native.MakeWritable(_Data);
				DetourHelper.Native.Copy(_BackupNative, _Data.Method, _Data.Type);
				DetourHelper.Native.MakeExecutable(_Data);
				DetourHelper.Native.FlushICache(_Data);
			}
		}

		public void ChangeSource(IntPtr newSource)
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("NativeDetour");
			}
			NativeDetourData data = _Data;
			_Data = DetourHelper.Native.Create(newSource, _Data.Target);
			IsApplied = false;
			Apply();
			DetourHelper.Native.Free(data);
		}

		public void ChangeTarget(IntPtr newTarget)
		{
			if (!IsValid)
			{
				throw new ObjectDisposedException("NativeDetour");
			}
			NativeDetourData data = _Data;
			_Data = DetourHelper.Native.Create(_Data.Method, newTarget);
			IsApplied = false;
			Apply();
			DetourHelper.Native.Free(data);
		}

		public void Free()
		{
			if (!IsValid)
			{
				return;
			}
			IsValid = false;
			DetourHelper.Native.MemFree(_BackupNative);
			DetourHelper.Native.Free(_Data);
			if (IsApplied)
			{
				return;
			}
			foreach (MethodBase item in _Pinned)
			{
				item.Unpin();
			}
			_Pinned.Clear();
		}

		public void Dispose()
		{
			if (IsValid)
			{
				Undo();
				Free();
			}
		}

		public MethodBase GenerateTrampoline(MethodBase signature = null)
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0198: Expected O, but got Unknown
			//IL_01b2: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			Func<NativeDetour, MethodBase, MethodBase> onGenerateTrampoline = OnGenerateTrampoline;
			MethodBase methodBase = ((onGenerateTrampoline != null) ? Extensions.InvokeWhileNull<MethodBase>((MulticastDelegate)onGenerateTrampoline, new object[2] { this, signature }) : null);
			if ((object)methodBase != null)
			{
				return methodBase;
			}
			if (!IsValid)
			{
				throw new ObjectDisposedException("NativeDetour");
			}
			if ((object)_BackupMethod != null)
			{
				return _BackupMethod;
			}
			if ((object)signature == null)
			{
				throw new ArgumentNullException("A signature must be given if the NativeDetour doesn't hold a reference to a managed method.");
			}
			MethodBase methodBase2 = Method;
			if ((object)methodBase2 == null)
			{
				methodBase2 = DetourHelper.GenerateNativeProxy(_Data.Method, signature);
			}
			Type type = (signature as MethodInfo)?.ReturnType ?? typeof(void);
			ParameterInfo[] parameters = signature.GetParameters();
			Type[] array = new Type[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				array[i] = parameters[i].ParameterType;
			}
			MethodBase method = Method;
			DynamicMethodDefinition val = new DynamicMethodDefinition(string.Format("Trampoline:Native<{0}>?{1}", (((object)method != null) ? Extensions.GetID(method, (string)null, (string)null, true, false, true) : null) ?? ((long)_Data.Method).ToString("X16", CultureInfo.InvariantCulture), GetHashCode()), type, array);
			try
			{
				ILProcessor iLProcessor = val.GetILProcessor();
				ExceptionHandler val2 = new ExceptionHandler((ExceptionHandlerType)2);
				iLProcessor.Body.ExceptionHandlers.Add(val2);
				iLProcessor.EmitDetourCopy(_BackupNative, _Data.Method, _Data.Type);
				VariableDefinition val3 = null;
				if ((object)type != typeof(void))
				{
					Collection<VariableDefinition> variables = iLProcessor.Body.Variables;
					VariableDefinition val4 = new VariableDefinition(Extensions.Import(iLProcessor, type));
					val3 = val4;
					variables.Add(val4);
				}
				int count = iLProcessor.Body.Instructions.Count;
				for (int j = 0; j < array.Length; j++)
				{
					iLProcessor.Emit(OpCodes.Ldarg, j);
				}
				if (methodBase2 is MethodInfo)
				{
					Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)(MethodInfo)methodBase2);
				}
				else
				{
					if (!(methodBase2 is ConstructorInfo))
					{
						throw new NotSupportedException("Method type " + methodBase2.GetType().FullName + " not supported.");
					}
					Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)(ConstructorInfo)methodBase2);
				}
				if (val3 != null)
				{
					iLProcessor.Emit(OpCodes.Stloc, val3);
				}
				Extensions.Emit(iLProcessor, OpCodes.Leave, (object)null);
				Instruction obj = iLProcessor.Body.Instructions[iLProcessor.Body.Instructions.Count - 1];
				int count2 = iLProcessor.Body.Instructions.Count;
				_ = iLProcessor.Body.Instructions.Count;
				iLProcessor.EmitDetourApply(_Data);
				int count3 = iLProcessor.Body.Instructions.Count;
				Instruction val5 = null;
				if (val3 != null)
				{
					iLProcessor.Emit(OpCodes.Ldloc, val3);
					val5 = iLProcessor.Body.Instructions[iLProcessor.Body.Instructions.Count - 1];
				}
				iLProcessor.Emit(OpCodes.Ret);
				val5 = val5 ?? iLProcessor.Body.Instructions[iLProcessor.Body.Instructions.Count - 1];
				obj.Operand = val5;
				val2.TryStart = iLProcessor.Body.Instructions[count];
				val2.TryEnd = iLProcessor.Body.Instructions[count2];
				val2.HandlerStart = iLProcessor.Body.Instructions[count2];
				val2.HandlerEnd = iLProcessor.Body.Instructions[count3];
				return val.Generate();
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		public T GenerateTrampoline<T>() where T : Delegate
		{
			if (!typeof(Delegate).IsAssignableFrom(typeof(T)))
			{
				throw new InvalidOperationException($"Type {typeof(T)} not a delegate type.");
			}
			return Extensions.CreateDelegate(GenerateTrampoline(typeof(T).GetMethod("Invoke")), typeof(T)) as T;
		}
	}
	internal static class DetourSorter<T> where T : ISortableDetour
	{
		private sealed class Group
		{
			public readonly string StepName;

			public List<T> Items = new List<T>();

			public List<Group> Children = new List<Group>();

			public List<Group> NonMatching = new List<Group>();

			public Group(string stepName)
			{
				StepName = stepName;
			}

			public Group(string stepName, List<T> items)
				: this(stepName)
			{
				Items.AddRange(items);
			}

			public void Step(Step step)
			{
				if (Children.Count != 0)
				{
					foreach (Group child in Children)
					{
						child.Step(step);
					}
					return;
				}
				if (Items.Count <= 1)
				{
					return;
				}
				if ((Items.Count == 2 && !((!step.IsFlat) ?? false)) || step.IsFlat.GetValueOrDefault())
				{
					Items.Sort(step);
					return;
				}
				string name = step.GetType().Name;
				Group group = new Group(name, new List<T> { Items[0] });
				Children.Add(group);
				for (int i = 1; i < Items.Count; i++)
				{
					T val = Items[i];
					if (step.Any(group.Items, val))
					{
						Group group2 = group;
						group = null;
						if (Children.Count > 1)
						{
							foreach (Group child2 in Children)
							{
								if (child2 != group2 && !step.Any(child2.Items, val) && !step.Any(child2.NonMatching, val))
								{
									group = child2;
									break;
								}
							}
						}
						if (group == null)
						{
							group = new Group(name);
							Children.Add(group);
							group.NonMatching.Add(group2);
							group2.NonMatching.Add(group);
						}
					}
					group.Items.Add(val);
				}
				if (Children.Count == 1)
				{
					Children.Clear();
				}
				else
				{
					Children.Sort(step.ForGroup);
				}
			}

			public void Flatten()
			{
				if (Children.Count != 0)
				{
					Items.Clear();
					Flatten(Items);
				}
			}

			public void Flatten(List<T> total)
			{
				if (Children.Count == 0)
				{
					total.AddRange(Items);
					return;
				}
				foreach (Group child in Children)
				{
					child.Flatten(total);
				}
			}
		}

		private abstract class Step : IComparer<T>
		{
			public abstract GroupComparer ForGroup { get; }

			public virtual bool? IsFlat => null;

			public abstract int Compare(T x, T y);

			public bool Any(List<T> xlist, T y)
			{
				foreach (T item in xlist)
				{
					if (Compare(item, y) != 0)
					{
						return true;
					}
				}
				return false;
			}

			public bool Any(List<Group> groups, T y)
			{
				foreach (Group group in groups)
				{
					if (Any(group.Items, y))
					{
						return true;
					}
				}
				return false;
			}
		}

		private sealed class GroupComparer : IComparer<Group>
		{
			public Step Step;

			public GroupComparer(Step step)
			{
				Step = step;
			}

			public int Compare(Group xg, Group yg)
			{
				foreach (T item in xg.Items)
				{
					foreach (T item2 in yg.Items)
					{
						int result;
						if ((result = Step.Compare(item, item2)) != 0)
						{
							return result;
						}
					}
				}
				return 0;
			}
		}

		private sealed class BeforeAfterAll : Step
		{
			public static readonly BeforeAfterAll _ = new BeforeAfterAll();

			public static readonly GroupComparer Group = new GroupComparer(_);

			public override GroupComparer ForGroup => Group;

			public override bool? IsFlat => false;

			public override int Compare(T a, T b)
			{
				if (a.Before.Contains("*") && !b.Before.Contains("*"))
				{
					return -1;
				}
				if (!a.Before.Contains("*") && b.Before.Contains("*"))
				{
					return 1;
				}
				if (a.After.Contains("*") && !b.After.Contains("*"))
				{
					return 1;
				}
				if (!a.After.Contains("*") && b.After.Contains("*"))
				{
					return -1;
				}
				return 0;
			}
		}

		private sealed class BeforeAfter : Step
		{
			public static readonly BeforeAfter _ = new BeforeAfter();

			public static readonly GroupComparer Group = new GroupComparer(_);

			public override GroupComparer ForGroup => Group;

			public override int Compare(T a, T b)
			{
				if (a.Before.Contains(b.ID))
				{
					return -1;
				}
				if (a.After.Contains(b.ID))
				{
					return 1;
				}
				if (b.Before.Contains(a.ID))
				{
					return 1;
				}
				if (b.After.Contains(a.ID))
				{
					return -1;
				}
				return 0;
			}
		}

		private sealed class Priority : Step
		{
			public static readonly Priority _ = new Priority();

			public static readonly GroupComparer Group = new GroupComparer(_);

			public override GroupComparer ForGroup => Group;

			public override int Compare(T a, T b)
			{
				int num = a.Priority - b.Priority;
				if (num != 0)
				{
					return num;
				}
				return 0;
			}
		}

		private sealed class GlobalIndex : Step
		{
			public static readonly GlobalIndex _ = new GlobalIndex();

			public static readonly GroupComparer Group = new GroupComparer(_);

			public override GroupComparer ForGroup => Group;

			public override int Compare(T a, T b)
			{
				return a.GlobalIndex.CompareTo(b.GlobalIndex);
			}
		}

		public static void Sort(List<T> detours)
		{
			lock (detours)
			{
				if (detours.Count > 1)
				{
					detours.Sort(GlobalIndex._);
					Group group = new Group("Init", detours);
					group.Step(BeforeAfterAll._);
					group.Step(BeforeAfter._);
					group.Step(Priority._);
					group.Step(GlobalIndex._);
					detours.Clear();
					group.Flatten(detours);
				}
			}
		}
	}
	public static class DetourHelper
	{
		private static readonly object _RuntimeLock = new object();

		private static bool _RuntimeInit = false;

		private static IDetourRuntimePlatform _Runtime;

		private static readonly object _NativeLock = new object();

		private static bool _NativeInit = false;

		private static IDetourNativePlatform _Native;

		private static readonly FieldInfo _f_Native = typeof(DetourHelper).GetField("_Native", BindingFlags.Static | BindingFlags.NonPublic);

		private static readonly MethodInfo _m_ToNativeDetourData = typeof(DetourHelper).GetMethod("ToNativeDetourData", BindingFlags.Static | BindingFlags.NonPublic);

		private static readonly MethodInfo _m_Copy = typeof(IDetourNativePlatform).GetMethod("Copy");

		private static readonly MethodInfo _m_Apply = typeof(IDetourNativePlatform).GetMethod("Apply");

		private static readonly ConstructorInfo _ctor_Exception = typeof(Exception).GetConstructor(new Type[1] { typeof(string) });

		public static IDetourRuntimePlatform Runtime
		{
			get
			{
				if (_Runtime != null)
				{
					return _Runtime;
				}
				lock (_RuntimeLock)
				{
					if (_Runtime != null)
					{
						return _Runtime;
					}
					if (_RuntimeInit)
					{
						return null;
					}
					_RuntimeInit = true;
					if ((object)Type.GetType("Mono.Runtime") != null)
					{
						_Runtime = new DetourRuntimeMonoPlatform();
					}
					else if (typeof(object).Assembly.GetName().Name == "System.Private.CoreLib")
					{
						_Runtime = DetourRuntimeNETCorePlatform.Create();
					}
					else
					{
						_Runtime = new DetourRuntimeNETPlatform();
					}
					return _Runtime;
				}
			}
			set
			{
				_Runtime = value;
			}
		}

		public static IDetourNativePlatform Native
		{
			get
			{
				if (_Native != null)
				{
					return _Native;
				}
				lock (_NativeLock)
				{
					if (_Native != null)
					{
						return _Native;
					}
					if (_NativeInit)
					{
						return null;
					}
					_NativeInit = true;
					IDetourNativePlatform detourNativePlatform = ((!PlatformHelper.Is((Platform)65536)) ? ((IDetourNativePlatform)new DetourNativeX86Platform()) : ((IDetourNativePlatform)new DetourNativeARMPlatform()));
					if (PlatformHelper.Is((Platform)37))
					{
						return _Native = new DetourNativeWindowsPlatform(detourNativePlatform);
					}
					if ((object)Type.GetType("Mono.Runtime") != null)
					{
						try
						{
							return _Native = new DetourNativeMonoPlatform(detourNativePlatform, "libmonosgen-2.0." + PlatformHelper.LibrarySuffix);
						}
						catch
						{
						}
					}
					string environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_RUNTIMEDETOUR_MONOPOSIXHELPER");
					if (((object)Type.GetType("Mono.Runtime") != null && environmentVariable != "0") || environmentVariable == "1")
					{
						try
						{
							return _Native = new DetourNativeMonoPosixPlatform(detourNativePlatform);
						}
						catch
						{
						}
					}
					try
					{
						return _Native = new DetourNativeLibcPlatform(detourNativePlatform);
					}
					catch
					{
					}
					return detourNativePlatform;
				}
			}
			set
			{
				_Native = value;
			}
		}

		public static void MakeWritable(this IDetourNativePlatform plat, NativeDetourData detour)
		{
			plat.MakeWritable(detour.Method, detour.Size);
		}

		public static void MakeExecutable(this IDetourNativePlatform plat, NativeDetourData detour)
		{
			plat.MakeExecutable(detour.Method, detour.Size);
		}

		public static void FlushICache(this IDetourNativePlatform plat, NativeDetourData detour)
		{
			plat.FlushICache(detour.Method, detour.Size);
		}

		public unsafe static void Write(this IntPtr to, ref int offs, byte value)
		{
			*(byte*)((long)to + offs) = value;
			offs++;
		}

		public unsafe static void Write(this IntPtr to, ref int offs, ushort value)
		{
			*(ushort*)((long)to + offs) = value;
			offs += 2;
		}

		public unsafe static void Write(this IntPtr to, ref int offs, uint value)
		{
			*(uint*)((long)to + offs) = value;
			offs += 4;
		}

		public unsafe static void Write(this IntPtr to, ref int offs, ulong value)
		{
			*(ulong*)((long)to + offs) = value;
			offs += 8;
		}

		public static MethodBase GetIdentifiable(this MethodBase method)
		{
			return Runtime.GetIdentifiable(method);
		}

		public static IntPtr GetNativeStart(this MethodBase method)
		{
			return Runtime.GetNativeStart(method);
		}

		public static IntPtr GetNativeStart(this Delegate method)
		{
			return method.Method.GetNativeStart();
		}

		public static IntPtr GetNativeStart(this Expression method)
		{
			return ((MethodCallExpression)method).Method.GetNativeStart();
		}

		public static MethodInfo CreateILCopy(this MethodBase method)
		{
			return Runtime.CreateCopy(method);
		}

		public static bool TryCreateILCopy(this MethodBase method, out MethodInfo dm)
		{
			return Runtime.TryCreateCopy(method, out dm);
		}

		public static T Pin<T>(this T method) where T : MethodBase
		{
			Runtime.Pin(method);
			return method;
		}

		public static T Unpin<T>(this T method) where T : MethodBase
		{
			Runtime.Unpin(method);
			return method;
		}

		public static MethodInfo GenerateNativeProxy(IntPtr target, MethodBase signature)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			Type type = (signature as MethodInfo)?.ReturnType ?? typeof(void);
			ParameterInfo[] parameters = signature.GetParameters();
			Type[] array = new Type[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				array[i] = parameters[i].ParameterType;
			}
			DynamicMethodDefinition val = new DynamicMethodDefinition("Native<" + ((long)target).ToString("X16", CultureInfo.InvariantCulture) + ">", type, array);
			MethodInfo methodInfo;
			try
			{
				methodInfo = val.StubCriticalDetour().Generate().Pin();
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			NativeDetourData detour = Native.Create(methodInfo.GetNativeStart(), target);
			Native.MakeWritable(detour);
			Native.Apply(detour);
			Native.MakeExecutable(detour);
			Native.FlushICache(detour);
			Native.Free(detour);
			return methodInfo;
		}

		private static NativeDetourData ToNativeDetourData(IntPtr method, IntPtr target, uint size, byte type, IntPtr extra)
		{
			NativeDetourData result = default(NativeDetourData);
			result.Method = method;
			result.Target = target;
			result.Size = size;
			result.Type = type;
			result.Extra = extra;
			return result;
		}

		public static DynamicMethodDefinition StubCriticalDetour(this DynamicMethodDefinition dm)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			ILProcessor iLProcessor = dm.GetILProcessor();
			ModuleDefinition module = ((MemberReference)iLProcessor.Body.Method).Module;
			for (int i = 0; i < 32; i++)
			{
				iLProcessor.Emit(OpCodes.Nop);
			}
			iLProcessor.Emit(OpCodes.Ldstr, ((MemberReference)dm.Definition).Name + " should've been detoured!");
			iLProcessor.Emit(OpCodes.Newobj, module.ImportReference((MethodBase)_ctor_Exception));
			iLProcessor.Emit(OpCodes.Throw);
			return dm;
		}

		public static void EmitDetourCopy(this ILProcessor il, IntPtr src, IntPtr dst, byte type)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			ModuleDefinition module = ((MemberReference)il.Body.Method).Module;
			il.Emit(OpCodes.Ldsfld, module.ImportReference(_f_Native));
			il.Emit(OpCodes.Ldc_I8, (long)src);
			il.Emit(OpCodes.Conv_I);
			il.Emit(OpCodes.Ldc_I8, (long)dst);
			il.Emit(OpCodes.Conv_I);
			il.Emit(OpCodes.Ldc_I4, (int)type);
			il.Emit(OpCodes.Conv_U1);
			il.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)_m_Copy));
		}

		public static void EmitDetourApply(this ILProcessor il, NativeDetourData data)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			ModuleDefinition module = ((MemberReference)il.Body.Method).Module;
			il.Emit(OpCodes.Ldsfld, module.ImportReference(_f_Native));
			il.Emit(OpCodes.Ldc_I8, (long)data.Method);
			il.Emit(OpCodes.Conv_I);
			il.Emit(OpCodes.Ldc_I8, (long)data.Target);
			il.Emit(OpCodes.Conv_I);
			il.Emit(OpCodes.Ldc_I4, (int)data.Size);
			il.Emit(OpCodes.Ldc_I4, (int)data.Type);
			il.Emit(OpCodes.Conv_U1);
			il.Emit(OpCodes.Ldc_I8, (long)data.Extra);
			il.Emit(OpCodes.Conv_I);
			il.Emit(OpCodes.Call, module.ImportReference((MethodBase)_m_ToNativeDetourData));
			il.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)_m_Apply));
		}
	}
	public interface IDetourNativePlatform
	{
		NativeDetourData Create(IntPtr from, IntPtr to, byte? type = null);

		void Free(NativeDetourData detour);

		void Apply(NativeDetourData detour);

		void Copy(IntPtr src, IntPtr dst, byte type);

		void MakeWritable(IntPtr src, uint size);

		void MakeExecutable(IntPtr src, uint size);

		void MakeReadWriteExecutable(IntPtr src, uint size);

		void FlushICache(IntPtr src, uint size);

		IntPtr MemAlloc(uint size);

		void MemFree(IntPtr ptr);
	}
	public interface IDetourRuntimePlatform
	{
		bool OnMethodCompiledWillBeCalled { get; }

		event OnMethodCompiledEvent OnMethodCompiled;

		MethodBase GetIdentifiable(MethodBase method);

		IntPtr GetNativeStart(MethodBase method);

		MethodInfo CreateCopy(MethodBase method);

		bool TryCreateCopy(MethodBase method, out MethodInfo dm);

		void Pin(MethodBase method);

		void Unpin(MethodBase method);

		MethodBase GetDetourTarget(MethodBase from, MethodBase to);

		uint TryMemAllocScratchCloseTo(IntPtr target, out IntPtr ptr, int size);
	}
	public delegate void OnMethodCompiledEvent(MethodBase method, IntPtr codeStart, ulong codeSize);
	public struct NativeDetourData
	{
		public IntPtr Method;

		public IntPtr Target;

		public byte Type;

		public uint Size;

		public IntPtr Extra;
	}
}
namespace MonoMod.RuntimeDetour.Platforms
{
	public class DetourNativeARMPlatform : IDetourNativePlatform
	{
		public enum DetourType : byte
		{
			Thumb,
			ThumbBX,
			AArch32,
			AArch32BX,
			AArch64
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int d_flushicache(IntPtr code, ulong size);

		private static readonly uint[] DetourSizes = new uint[5] { 8u, 12u, 8u, 12u, 16u };

		public bool ShouldFlushICache = true;

		private readonly byte[] _FlushCache32 = new byte[44]
		{
			128, 64, 45, 233, 0, 48, 160, 225, 1, 192,
			128, 224, 20, 224, 159, 229, 3, 0, 160, 225,
			12, 16, 160, 225, 14, 112, 160, 225, 0, 32,
			160, 227, 0, 0, 0, 239, 128, 128, 189, 232,
			2, 0, 15, 0
		};

		private readonly byte[] _FlushCache64 = new byte[76]
		{
			1, 0, 1, 139, 0, 244, 126, 146, 63, 0,
			0, 235, 201, 0, 0, 84, 226, 3, 0, 170,
			34, 126, 11, 213, 66, 16, 0, 145, 63, 0,
			2, 235, 168, 255, 255, 84, 159, 59, 3, 213,
			63, 0, 0, 235, 169, 0, 0, 84, 32, 117,
			11, 213, 0, 16, 0, 145, 63, 0, 0, 235,
			168, 255, 255, 84, 159, 59, 3, 213, 223, 63,
			3, 213, 192, 3, 95, 214
		};

		private static DetourType GetDetourType(IntPtr from, IntPtr to)
		{
			if (IntPtr.Size >= 8)
			{
				return DetourType.AArch64;
			}
			bool num = ((long)from & 1) == 1;
			bool flag = ((long)to & 1) == 1;
			if (num)
			{
				if (flag)
				{
					return DetourType.Thumb;
				}
				return DetourType.ThumbBX;
			}
			if (flag)
			{
				return DetourType.AArch32BX;
			}
			return DetourType.AArch32;
		}

		public NativeDetourData Create(IntPtr from, IntPtr to, byte? type)
		{
			NativeDetourData nativeDetourData = default(NativeDetourData);
			nativeDetourData.Method = (IntPtr)((long)from & -2);
			nativeDetourData.Target = (IntPtr)((long)to & -2);
			NativeDetourData result = nativeDetourData;
			uint[] detourSizes = DetourSizes;
			int num = ((int?)type) ?? ((int)GetDetourType(from, to));
			byte b = (byte)num;
			result.Type = (byte)num;
			result.Size = detourSizes[b];
			return result;
		}

		public void Free(NativeDetourData detour)
		{
		}

		public void Apply(NativeDetourData detour)
		{
			int offs = 0;
			switch ((DetourType)detour.Type)
			{
			case DetourType.Thumb:
				detour.Method.Write(ref offs, 223);
				detour.Method.Write(ref offs, 248);
				detour.Method.Write(ref offs, 0);
				detour.Method.Write(ref offs, 240);
				detour.Method.Write(ref offs, (uint)(int)detour.Target | 1u);
				break;
			case DetourType.ThumbBX:
				detour.Method.Write(ref offs, 223);
				detour.Method.Write(ref offs, 248);
				detour.Method.Write(ref offs, 4);
				detour.Method.Write(ref offs, 160);
				detour.Method.Write(ref offs, 80);
				detour.Method.Write(ref offs, 71);
				detour.Method.Write(ref offs, 0);
				detour.Method.Write(ref offs, 191);
				detour.Method.Write(ref offs, (uint)(int)detour.Target | 0u);
				break;
			case DetourType.AArch32:
				detour.Method.Write(ref offs, 4);
				detour.Method.Write(ref offs, 240);
				detour.Method.Write(ref offs, 31);
				detour.Method.Write(ref offs, 229);
				detour.Method.Write(ref offs, (uint)(int)detour.Target | 0u);
				break;
			case DetourType.AArch32BX:
				detour.Method.Write(ref offs, 0);
				detour.Method.Write(ref offs, 128);
				detour.Method.Write(ref offs, 159);
				detour.Method.Write(ref offs, 229);
				detour.Method.Write(ref offs, 24);
				detour.Method.Write(ref offs, byte.MaxValue);
				detour.Method.Write(ref offs, 47);
				detour.Method.Write(ref offs, 225);
				detour.Method.Write(ref offs, (uint)(int)detour.Target | 1u);
				break;
			case DetourType.AArch64:
				detour.Method.Write(ref offs, 79);
				detour.Method.Write(ref offs, 0);
				detour.Method.Write(ref offs, 0);
				detour.Method.Write(ref offs, 88);
				detour.Method.Write(ref offs, 224);
				detour.Method.Write(ref offs, 1);
				detour.Method.Write(ref offs, 31);
				detour.Method.Write(ref offs, 214);
				detour.Method.Write(ref offs, (ulong)(long)detour.Target);
				break;
			default:
				throw new NotSupportedException($"Unknown detour type {detour.Type}");
			}
		}

		public unsafe void Copy(IntPtr src, IntPtr dst, byte type)
		{
			switch ((DetourType)type)
			{
			case DetourType.Thumb:
				*(int*)(long)dst = *(int*)(long)src;
				*(int*)((long)dst + 4) = *(int*)((long)src + 4);
				break;
			case DetourType.ThumbBX:
				*(int*)(long)dst = *(int*)(long)src;
				*(short*)((long)dst + 4) = *(short*)((long)src + 4);
				*(short*)((long)dst + 6) = *(short*)((long)src + 6);
				*(int*)((long)dst + 8) = *(int*)((long)src + 8);
				break;
			case DetourType.AArch32:
				*(int*)(long)dst = *(int*)(long)src;
				*(int*)((long)dst + 4) = *(int*)((long)src + 4);
				break;
			case DetourType.AArch32BX:
				*(int*)(long)dst = *(int*)(long)src;
				*(int*)((long)dst + 4) = *(int*)((long)src + 4);
				*(int*)((long)dst + 8) = *(int*)((long)src + 8);
				break;
			case DetourType.AArch64:
				*(int*)(long)dst = *(int*)(long)src;
				*(int*)((long)dst + 4) = *(int*)((long)src + 4);
				*(long*)((long)dst + 8) = *(long*)((long)src + 8);
				break;
			default:
				throw new NotSupportedException($"Unknown detour type {type}");
			}
		}

		public void MakeWritable(IntPtr src, uint size)
		{
		}

		public void MakeExecutable(IntPtr src, uint size)
		{
		}

		public void MakeReadWriteExecutable(IntPtr src, uint size)
		{
		}

		public unsafe void FlushICache(IntPtr src, uint size)
		{
			if (ShouldFlushICache)
			{
				byte[] array = ((IntPtr.Size >= 8) ? _FlushCache64 : _FlushCache32);
				fixed (byte* ptr = array)
				{
					DetourHelper.Native.MakeExecutable((IntPtr)ptr, (uint)array.Length);
					(Marshal.GetDelegateForFunctionPointer((IntPtr)ptr, typeof(d_flushicache)) as d_flushicache)(src, size);
				}
			}
		}

		public IntPtr MemAlloc(uint size)
		{
			return Marshal.AllocHGlobal((int)size);
		}

		public void MemFree(IntPtr ptr)
		{
			Marshal.FreeHGlobal(ptr);
		}
	}
	public class DetourNativeLibcPlatform : IDetourNativePlatform
	{
		[Flags]
		private enum MmapProts
		{
			PROT_READ = 1,
			PROT_WRITE = 2,
			PROT_EXEC = 4,
			PROT_NONE = 0,
			PROT_GROWSDOWN = 0x1000000,
			PROT_GROWSUP = 0x2000000
		}

		private readonly IDetourNativePlatform Inner;

		private readonly long _Pagesize;

		public DetourNativeLibcPlatform(IDetourNativePlatform inner)
		{
			Inner = inner;
			PropertyInfo property = typeof(Environment).GetProperty("SystemPageSize");
			if ((object)property == null)
			{
				throw new NotSupportedException("Unsupported runtime");
			}
			_Pagesize = (int)property.GetValue(null, new object[0]);
		}

		private void SetMemPerms(IntPtr start, ulong len, MmapProts prot)
		{
			long pagesize = _Pagesize;
			long num = (long)start & ~(pagesize - 1);
			long num2 = ((long)start + (long)len + pagesize - 1) & ~(pagesize - 1);
			if (mprotect((IntPtr)num, (IntPtr)(num2 - num), prot) != 0)
			{
				throw new Win32Exception();
			}
		}

		public void MakeWritable(IntPtr src, uint size)
		{
			SetMemPerms(src, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC);
		}

		public void MakeExecutable(IntPtr src, uint size)
		{
			SetMemPerms(src, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC);
		}

		public void MakeReadWriteExecutable(IntPtr

BepInEx/core/MonoMod.Utils.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Utils;
using MonoMod.Utils.Cil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("MonoMod.Utils.Cil.ILGeneratorProxy")]
[assembly: AssemblyCompany("0x0ade")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2022 0x0ade")]
[assembly: AssemblyDescription("Utilities and smaller MonoMod \"components\" (f.e. ModInterop, DynDll, DynData). Can be used for your own mods. Required by all other MonoMod components.")]
[assembly: AssemblyFileVersion("22.1.29.1")]
[assembly: AssemblyInformationalVersion("22.01.29.01")]
[assembly: AssemblyProduct("MonoMod.Utils")]
[assembly: AssemblyTitle("MonoMod.Utils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("22.1.29.1")]
[module: UnverifiableCode]
internal static class MultiTargetShims
{
	private static readonly object[] _NoArgs = new object[0];

	public static string Replace(this string self, string oldValue, string newValue, StringComparison comparison)
	{
		return self.Replace(oldValue, newValue);
	}

	public static bool Contains(this string self, string value, StringComparison comparison)
	{
		return self.Contains(value);
	}

	public static int GetHashCode(this string self, StringComparison comparison)
	{
		return self.GetHashCode();
	}

	public static int IndexOf(this string self, char value, StringComparison comparison)
	{
		return self.IndexOf(value);
	}

	public static int IndexOf(this string self, string value, StringComparison comparison)
	{
		return self.IndexOf(value);
	}

	public static TypeReference GetConstraintType(this TypeReference type)
	{
		return type;
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	public class IgnoresAccessChecksToAttribute : Attribute
	{
		public string AssemblyName { get; }

		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
			AssemblyName = assemblyName;
		}
	}
}
namespace MonoMod
{
	internal static class MMDbgLog
	{
		public static readonly string Tag;

		public static TextWriter Writer;

		public static bool Debugging;

		static MMDbgLog()
		{
			Tag = typeof(MMDbgLog).Assembly.GetName().Name;
			if (!(Environment.GetEnvironmentVariable("MONOMOD_DBGLOG") == "1"))
			{
				string? environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_DBGLOG");
				bool? obj;
				if (environmentVariable == null)
				{
					obj = null;
				}
				else
				{
					string text = environmentVariable.ToLower(CultureInfo.InvariantCulture);
					obj = ((text != null) ? new bool?(MultiTargetShims.Contains(text, Tag.ToLower(CultureInfo.InvariantCulture), StringComparison.Ordinal)) : null);
				}
				bool? flag = obj;
				if (!flag.GetValueOrDefault())
				{
					return;
				}
			}
			Start();
		}

		public static void WaitForDebugger()
		{
			if (!Debugging)
			{
				Debugging = true;
				Debugger.Launch();
				Thread.Sleep(6000);
				Debugger.Break();
			}
		}

		public static void Start()
		{
			if (Writer != null)
			{
				return;
			}
			string text = Environment.GetEnvironmentVariable("MONOMOD_DBGLOG_PATH");
			if (text == "-")
			{
				Writer = Console.Out;
				return;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "mmdbglog.txt";
			}
			text = Path.GetFullPath(Path.GetFileNameWithoutExtension(text) + "-" + Tag + Path.GetExtension(text));
			try
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
			catch
			{
			}
			try
			{
				string directoryName = Path.GetDirectoryName(text);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				Writer = new StreamWriter(new FileStream(text, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete), Encoding.UTF8);
			}
			catch
			{
			}
		}

		public static void Log(string str)
		{
			TextWriter writer = Writer;
			if (writer != null)
			{
				writer.WriteLine(str);
				writer.Flush();
			}
		}

		public static T Log<T>(string str, T value)
		{
			TextWriter writer = Writer;
			if (writer == null)
			{
				return value;
			}
			writer.WriteLine(string.Format(CultureInfo.InvariantCulture, str, new object[1] { value }));
			writer.Flush();
			return value;
		}
	}
}
namespace MonoMod.ModInterop
{
	[AttributeUsage(AttributeTargets.Class)]
	public sealed class ModExportNameAttribute : Attribute
	{
		public string Name;

		public ModExportNameAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)]
	public sealed class ModImportNameAttribute : Attribute
	{
		public string Name;

		public ModImportNameAttribute(string name)
		{
			Name = name;
		}
	}
	public static class ModInteropManager
	{
		private static HashSet<Type> Registered = new HashSet<Type>();

		private static Dictionary<string, List<MethodInfo>> Methods = new Dictionary<string, List<MethodInfo>>();

		private static List<FieldInfo> Fields = new List<FieldInfo>();

		public static void ModInterop(this Type type)
		{
			if (Registered.Contains(type))
			{
				return;
			}
			Registered.Add(type);
			string name = type.Assembly.GetName().Name;
			object[] customAttributes = type.GetCustomAttributes(typeof(ModExportNameAttribute), inherit: false);
			for (int i = 0; i < customAttributes.Length; i++)
			{
				name = ((ModExportNameAttribute)customAttributes[i]).Name;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType))
				{
					Fields.Add(fieldInfo);
				}
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo method in methods)
			{
				method.RegisterModExport();
				method.RegisterModExport(name);
			}
			foreach (FieldInfo field in Fields)
			{
				if (!Methods.TryGetValue(field.GetModImportName(), out var value))
				{
					field.SetValue(null, null);
					continue;
				}
				bool flag = false;
				foreach (MethodInfo item in value)
				{
					try
					{
						field.SetValue(null, Delegate.CreateDelegate(field.FieldType, null, item));
						flag = true;
					}
					catch
					{
						continue;
					}
					break;
				}
				if (!flag)
				{
					field.SetValue(null, null);
				}
			}
		}

		public static void RegisterModExport(this MethodInfo method, string prefix = null)
		{
			if (!method.IsPublic || !method.IsStatic)
			{
				throw new MemberAccessException("Utility must be public static");
			}
			string text = method.Name;
			if (!string.IsNullOrEmpty(prefix))
			{
				text = prefix + "." + text;
			}
			if (!Methods.TryGetValue(text, out var value))
			{
				value = (Methods[text] = new List<MethodInfo>());
			}
			if (!value.Contains(method))
			{
				value.Add(method);
			}
		}

		private static string GetModImportName(this FieldInfo field)
		{
			object[] customAttributes = field.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false);
			int num = 0;
			if (num < customAttributes.Length)
			{
				return ((ModImportNameAttribute)customAttributes[num]).Name;
			}
			customAttributes = field.DeclaringType.GetCustomAttributes(typeof(ModImportNameAttribute), inherit: false);
			num = 0;
			if (num < customAttributes.Length)
			{
				return ((ModImportNameAttribute)customAttributes[num]).Name + "." + field.Name;
			}
			return field.Name;
		}
	}
}
namespace MonoMod.Utils
{
	public sealed class DynData<TTarget> : IDisposable where TTarget : class
	{
		private class _Data_ : IDisposable
		{
			public readonly Dictionary<string, Func<TTarget, object>> Getters = new Dictionary<string, Func<TTarget, object>>();

			public readonly Dictionary<string, Action<TTarget, object>> Setters = new Dictionary<string, Action<TTarget, object>>();

			public readonly Dictionary<string, object> Data = new Dictionary<string, object>();

			public readonly HashSet<string> Disposable = new HashSet<string>();

			~_Data_()
			{
				Dispose();
			}

			public void Dispose()
			{
				lock (Data)
				{
					if (Data.Count == 0)
					{
						return;
					}
					foreach (string item in Disposable)
					{
						if (Data.TryGetValue(item, out var value) && value is IDisposable disposable)
						{
							disposable.Dispose();
						}
					}
					Disposable.Clear();
					Data.Clear();
				}
			}
		}

		private static int CreationsInProgress;

		private static readonly object[] _NoArgs;

		private static readonly _Data_ _DataStatic;

		private static readonly Dictionary<WeakReference, _Data_> _DataMap;

		private static readonly HashSet<WeakReference> _DataMapDead;

		private static readonly Dictionary<string, Func<TTarget, object>> _SpecialGetters;

		private static readonly Dictionary<string, Action<TTarget, object>> _SpecialSetters;

		private readonly WeakReference Weak;

		private TTarget KeepAlive;

		private readonly _Data_ _Data;

		public Dictionary<string, Func<TTarget, object>> Getters => _Data.Getters;

		public Dictionary<string, Action<TTarget, object>> Setters => _Data.Setters;

		public Dictionary<string, object> Data => _Data.Data;

		public bool IsAlive
		{
			get
			{
				if (Weak != null)
				{
					return Weak.SafeGetIsAlive();
				}
				return true;
			}
		}

		public TTarget Target => Weak?.SafeGetTarget() as TTarget;

		public object this[string name]
		{
			get
			{
				if (_SpecialGetters.TryGetValue(name, out var value) || Getters.TryGetValue(name, out value))
				{
					return value(Weak?.SafeGetTarget() as TTarget);
				}
				if (Data.TryGetValue(name, out var value2))
				{
					return value2;
				}
				return null;
			}
			set
			{
				if (_SpecialSetters.TryGetValue(name, out var value2) || Setters.TryGetValue(name, out value2))
				{
					value2(Weak?.SafeGetTarget() as TTarget, value);
					return;
				}
				object obj;
				if (_Data.Disposable.Contains(name) && (obj = this[name]) != null && obj is IDisposable disposable)
				{
					disposable.Dispose();
				}
				Data[name] = value;
			}
		}

		public static event Action<DynData<TTarget>, TTarget> OnInitialize;

		static DynData()
		{
			CreationsInProgress = 0;
			_NoArgs = new object[0];
			_DataStatic = new _Data_();
			_DataMap = new Dictionary<WeakReference, _Data_>(new WeakReferenceComparer());
			_DataMapDead = new HashSet<WeakReference>();
			_SpecialGetters = new Dictionary<string, Func<TTarget, object>>();
			_SpecialSetters = new Dictionary<string, Action<TTarget, object>>();
			GCListener.OnCollect += delegate
			{
				if (CreationsInProgress != 0)
				{
					return;
				}
				lock (_DataMap)
				{
					foreach (KeyValuePair<WeakReference, _Data_> item in _DataMap)
					{
						if (!item.Key.SafeGetIsAlive())
						{
							_DataMapDead.Add(item.Key);
							item.Value.Dispose();
						}
					}
					foreach (WeakReference item2 in _DataMapDead)
					{
						_DataMap.Remove(item2);
					}
					_DataMapDead.Clear();
				}
			};
			FieldInfo[] fields = typeof(TTarget).GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo field in fields)
			{
				string name = field.Name;
				_SpecialGetters[name] = (TTarget obj) => field.GetValue(obj);
				_SpecialSetters[name] = delegate(TTarget obj, object value)
				{
					field.SetValue(obj, value);
				};
			}
			PropertyInfo[] properties = typeof(TTarget).GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo in properties)
			{
				string name2 = propertyInfo.Name;
				MethodInfo get = propertyInfo.GetGetMethod(nonPublic: true);
				if ((object)get != null)
				{
					_SpecialGetters[name2] = (TTarget obj) => get.Invoke(obj, _NoArgs);
				}
				MethodInfo set = propertyInfo.GetSetMethod(nonPublic: true);
				if ((object)set != null)
				{
					_SpecialSetters[name2] = delegate(TTarget obj, object value)
					{
						set.Invoke(obj, new object[1] { value });
					};
				}
			}
		}

		public DynData()
			: this((TTarget)null, keepAlive: false)
		{
		}

		public DynData(TTarget obj)
			: this(obj, keepAlive: true)
		{
		}

		public DynData(TTarget obj, bool keepAlive)
		{
			if (obj != null)
			{
				WeakReference weakReference = new WeakReference(obj);
				WeakReference key = weakReference;
				CreationsInProgress++;
				lock (_DataMap)
				{
					if (!_DataMap.TryGetValue(key, out _Data))
					{
						_Data = new _Data_();
						_DataMap.Add(key, _Data);
					}
				}
				CreationsInProgress--;
				Weak = weakReference;
				if (keepAlive)
				{
					KeepAlive = obj;
				}
			}
			else
			{
				_Data = _DataStatic;
			}
			DynData<TTarget>.OnInitialize?.Invoke(this, obj);
		}

		public T Get<T>(string name)
		{
			return (T)this[name];
		}

		public void Set<T>(string name, T value)
		{
			this[name] = value;
		}

		public void RegisterProperty(string name, Func<TTarget, object> getter, Action<TTarget, object> setter)
		{
			Getters[name] = getter;
			Setters[name] = setter;
		}

		public void UnregisterProperty(string name)
		{
			Getters.Remove(name);
			Setters.Remove(name);
		}

		private void Dispose(bool disposing)
		{
			KeepAlive = null;
		}

		~DynData()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public static class Extensions
	{
		private static readonly Type t_StateMachineAttribute = typeof(object).Assembly.GetType("System.Runtime.CompilerServices.StateMachineAttribute");

		private static readonly PropertyInfo p_StateMachineType = t_StateMachineAttribute?.GetProperty("StateMachineType");

		private static readonly Type t_Code = typeof(Code);

		private static readonly Type t_OpCodes = typeof(OpCodes);

		private static readonly Dictionary<int, OpCode> _ToLongOp = new Dictionary<int, OpCode>();

		private static readonly Dictionary<int, OpCode> _ToShortOp = new Dictionary<int, OpCode>();

		private static readonly object[] _NoArgs = new object[0];

		private static readonly Dictionary<Type, FieldInfo> fmap_mono_assembly = new Dictionary<Type, FieldInfo>();

		private static readonly bool _MonoAssemblyNameHasArch = new AssemblyName("Dummy, ProcessorArchitecture=MSIL").ProcessorArchitecture == ProcessorArchitecture.MSIL;

		private static readonly Type _RTDynamicMethod = typeof(DynamicMethod).GetNestedType("RTDynamicMethod", BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly Type t_ParamArrayAttribute = typeof(ParamArrayAttribute);

		private static readonly FieldInfo f_GenericParameter_position = typeof(GenericParameter).GetField("position", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo f_GenericParameter_type = typeof(GenericParameter).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly Dictionary<Type, int> _GetManagedSizeCache = new Dictionary<Type, int> { 
		{
			typeof(void),
			0
		} };

		private static MethodInfo _GetManagedSizeHelper;

		private static readonly Dictionary<MethodBase, Func<IntPtr>> _GetLdftnPointerCache = new Dictionary<MethodBase, Func<IntPtr>>();

		public static string ToHexadecimalString(this byte[] data)
		{
			return MultiTargetShims.Replace(BitConverter.ToString(data), "-", string.Empty, StringComparison.Ordinal);
		}

		public static T InvokePassing<T>(this MulticastDelegate md, T val, params object[] args)
		{
			if ((object)md == null)
			{
				return val;
			}
			object[] array = new object[args.Length + 1];
			array[0] = val;
			Array.Copy(args, 0, array, 1, args.Length);
			Delegate[] invocationList = md.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				array[0] = invocationList[i].DynamicInvoke(array);
			}
			return (T)array[0];
		}

		public static bool InvokeWhileTrue(this MulticastDelegate md, params object[] args)
		{
			if ((object)md == null)
			{
				return true;
			}
			Delegate[] invocationList = md.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				if (!(bool)invocationList[i].DynamicInvoke(args))
				{
					return false;
				}
			}
			return true;
		}

		public static bool InvokeWhileFalse(this MulticastDelegate md, params object[] args)
		{
			if ((object)md == null)
			{
				return false;
			}
			Delegate[] invocationList = md.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				if ((bool)invocationList[i].DynamicInvoke(args))
				{
					return true;
				}
			}
			return false;
		}

		public static T InvokeWhileNull<T>(this MulticastDelegate md, params object[] args) where T : class
		{
			if ((object)md == null)
			{
				return null;
			}
			Delegate[] invocationList = md.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				T val = (T)invocationList[i].DynamicInvoke(args);
				if (val != null)
				{
					return val;
				}
			}
			return null;
		}

		public static string SpacedPascalCase(this string input)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < input.Length; i++)
			{
				char c = input[i];
				if (i > 0 && char.IsUpper(c))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		public static string ReadNullTerminatedString(this BinaryReader stream)
		{
			string text = "";
			char c;
			while ((c = stream.ReadChar()) != 0)
			{
				text += c;
			}
			return text;
		}

		public static void WriteNullTerminatedString(this BinaryWriter stream, string text)
		{
			if (text != null)
			{
				foreach (char ch in text)
				{
					stream.Write(ch);
				}
			}
			stream.Write('\0');
		}

		public static T CastDelegate<T>(this Delegate source) where T : class
		{
			return source.CastDelegate(typeof(T)) as T;
		}

		public static Delegate CastDelegate(this Delegate source, Type type)
		{
			if ((object)source == null)
			{
				return null;
			}
			Delegate[] invocationList = source.GetInvocationList();
			if (invocationList.Length == 1)
			{
				return CreateDelegate(invocationList[0].Method, type, invocationList[0].Target);
			}
			Delegate[] array = new Delegate[invocationList.Length];
			for (int i = 0; i < invocationList.Length; i++)
			{
				array[i] = invocationList[i].CastDelegate(type);
			}
			return Delegate.Combine(array);
		}

		public static bool TryCastDelegate<T>(this Delegate source, out T result) where T : class
		{
			if (source is T val)
			{
				result = val;
				return true;
			}
			Delegate result2;
			bool result3 = source.TryCastDelegate(typeof(T), out result2);
			result = result2 as T;
			return result3;
		}

		public static bool TryCastDelegate(this Delegate source, Type type, out Delegate result)
		{
			result = null;
			if ((object)source == null)
			{
				return false;
			}
			try
			{
				Delegate[] invocationList = source.GetInvocationList();
				if (invocationList.Length == 1)
				{
					result = CreateDelegate(invocationList[0].Method, type, invocationList[0].Target);
					return true;
				}
				Delegate[] array = new Delegate[invocationList.Length];
				for (int i = 0; i < invocationList.Length; i++)
				{
					array[i] = invocationList[i].CastDelegate(type);
				}
				result = Delegate.Combine(array);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public static void LogDetailed(this Exception e, string tag = null)
		{
			if (tag == null)
			{
				Console.WriteLine("--------------------------------");
				Console.WriteLine("Detailed exception log:");
			}
			for (Exception ex = e; ex != null; ex = ex.InnerException)
			{
				Console.WriteLine("--------------------------------");
				Console.WriteLine(ex.GetType().FullName + ": " + ex.Message + "\n" + ex.StackTrace);
				if (ex is ReflectionTypeLoadException ex2)
				{
					for (int i = 0; i < ex2.Types.Length; i++)
					{
						Console.WriteLine("ReflectionTypeLoadException.Types[" + i + "]: " + ex2.Types[i]);
					}
					for (int j = 0; j < ex2.LoaderExceptions.Length; j++)
					{
						ex2.LoaderExceptions[j].LogDetailed(tag + ((tag == null) ? "" : ", ") + "rtle:" + j);
					}
				}
				if (ex is TypeLoadException)
				{
					Console.WriteLine("TypeLoadException.TypeName: " + ((TypeLoadException)ex).TypeName);
				}
				if (ex is BadImageFormatException)
				{
					Console.WriteLine("BadImageFormatException.FileName: " + ((BadImageFormatException)ex).FileName);
				}
			}
		}

		public static MethodInfo GetStateMachineTarget(this MethodInfo method)
		{
			if ((object)p_StateMachineType == null)
			{
				return null;
			}
			object[] customAttributes = method.GetCustomAttributes(inherit: false);
			for (int i = 0; i < customAttributes.Length; i++)
			{
				Attribute attribute = (Attribute)customAttributes[i];
				if (t_StateMachineAttribute.IsCompatible(attribute.GetType()))
				{
					return (p_StateMachineType.GetValue(attribute, null) as Type)?.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
			}
			return null;
		}

		public static MethodBase GetActualGenericMethodDefinition(this MethodInfo method)
		{
			return (method.IsGenericMethod ? method.GetGenericMethodDefinition() : method).GetUnfilledMethodOnGenericType();
		}

		public static MethodBase GetUnfilledMethodOnGenericType(this MethodBase method)
		{
			if ((object)method.DeclaringType != null && method.DeclaringType.IsGenericType)
			{
				Type genericTypeDefinition = method.DeclaringType.GetGenericTypeDefinition();
				method = MethodBase.GetMethodFromHandle(method.MethodHandle, genericTypeDefinition.TypeHandle);
			}
			return method;
		}

		public static bool Is(this MemberReference member, string fullName)
		{
			if (member == null)
			{
				return false;
			}
			return MultiTargetShims.Replace(member.FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(fullName, "+", "/", StringComparison.Ordinal);
		}

		public static bool Is(this MemberReference member, string typeFullName, string name)
		{
			if (member == null)
			{
				return false;
			}
			if (MultiTargetShims.Replace(((MemberReference)member.DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(typeFullName, "+", "/", StringComparison.Ordinal))
			{
				return member.Name == name;
			}
			return false;
		}

		public static bool Is(this MemberReference member, Type type, string name)
		{
			if (member == null)
			{
				return false;
			}
			if (MultiTargetShims.Replace(((MemberReference)member.DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(type.FullName, "+", "/", StringComparison.Ordinal))
			{
				return member.Name == name;
			}
			return false;
		}

		public static bool Is(this MethodReference method, string fullName)
		{
			if (method == null)
			{
				return false;
			}
			if (MultiTargetShims.Contains(fullName, " ", StringComparison.Ordinal))
			{
				if (MultiTargetShims.Replace(method.GetID(null, null, withType: true, simple: true), "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(fullName, "+", "/", StringComparison.Ordinal))
				{
					return true;
				}
				if (MultiTargetShims.Replace(method.GetID(), "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(fullName, "+", "/", StringComparison.Ordinal))
				{
					return true;
				}
			}
			return MultiTargetShims.Replace(((MemberReference)method).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(fullName, "+", "/", StringComparison.Ordinal);
		}

		public static bool Is(this MethodReference method, string typeFullName, string name)
		{
			if (method == null)
			{
				return false;
			}
			if (MultiTargetShims.Contains(name, " ", StringComparison.Ordinal) && MultiTargetShims.Replace(((MemberReference)((MemberReference)method).DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(typeFullName, "+", "/", StringComparison.Ordinal) && MultiTargetShims.Replace(method.GetID(null, null, withType: false), "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(name, "+", "/", StringComparison.Ordinal))
			{
				return true;
			}
			if (MultiTargetShims.Replace(((MemberReference)((MemberReference)method).DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(typeFullName, "+", "/", StringComparison.Ordinal))
			{
				return ((MemberReference)method).Name == name;
			}
			return false;
		}

		public static bool Is(this MethodReference method, Type type, string name)
		{
			if (method == null)
			{
				return false;
			}
			if (MultiTargetShims.Contains(name, " ", StringComparison.Ordinal) && MultiTargetShims.Replace(((MemberReference)((MemberReference)method).DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(type.FullName, "+", "/", StringComparison.Ordinal) && MultiTargetShims.Replace(method.GetID(null, null, withType: false), "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(name, "+", "/", StringComparison.Ordinal))
			{
				return true;
			}
			if (MultiTargetShims.Replace(((MemberReference)((MemberReference)method).DeclaringType).FullName, "+", "/", StringComparison.Ordinal) == MultiTargetShims.Replace(type.FullName, "+", "/", StringComparison.Ordinal))
			{
				return ((MemberReference)method).Name == name;
			}
			return false;
		}

		public static void ReplaceOperands(this ILProcessor il, object from, object to)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<Instruction> enumerator = il.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					if (current.Operand?.Equals(from) ?? (from == null))
					{
						current.Operand = to;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public static FieldReference Import(this ILProcessor il, FieldInfo field)
		{
			return ((MemberReference)il.Body.Method).Module.ImportReference(field);
		}

		public static MethodReference Import(this ILProcessor il, MethodBase method)
		{
			return ((MemberReference)il.Body.Method).Module.ImportReference(method);
		}

		public static TypeReference Import(this ILProcessor il, Type type)
		{
			return ((MemberReference)il.Body.Method).Module.ImportReference(type);
		}

		public static MemberReference Import(this ILProcessor il, MemberInfo member)
		{
			if ((object)member == null)
			{
				throw new ArgumentNullException("member");
			}
			if (!(member is FieldInfo field))
			{
				if (!(member is MethodBase method))
				{
					if (member is Type type)
					{
						return (MemberReference)(object)il.Import(type);
					}
					throw new NotSupportedException("Unsupported member type " + member.GetType().FullName);
				}
				return (MemberReference)(object)il.Import(method);
			}
			return (MemberReference)(object)il.Import(field);
		}

		public static Instruction Create(this ILProcessor il, OpCode opcode, FieldInfo field)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return il.Create(opcode, il.Import(field));
		}

		public static Instruction Create(this ILProcessor il, OpCode opcode, MethodBase method)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (method is DynamicMethod)
			{
				return il.Create(opcode, (object)method);
			}
			return il.Create(opcode, il.Import(method));
		}

		public static Instruction Create(this ILProcessor il, OpCode opcode, Type type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return il.Create(opcode, il.Import(type));
		}

		public static Instruction Create(this ILProcessor il, OpCode opcode, object operand)
		{
			//IL_0001: 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)
			Instruction obj = il.Create(OpCodes.Nop);
			obj.OpCode = opcode;
			obj.Operand = operand;
			return obj;
		}

		public static Instruction Create(this ILProcessor il, OpCode opcode, MemberInfo member)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((object)member == null)
			{
				throw new ArgumentNullException("member");
			}
			if (!(member is FieldInfo field))
			{
				if (!(member is MethodBase method))
				{
					if (member is Type type)
					{
						return il.Create(opcode, type);
					}
					throw new NotSupportedException("Unsupported member type " + member.GetType().FullName);
				}
				return il.Create(opcode, method);
			}
			return il.Create(opcode, field);
		}

		public static void Emit(this ILProcessor il, OpCode opcode, FieldInfo field)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			il.Emit(opcode, il.Import(field));
		}

		public static void Emit(this ILProcessor il, OpCode opcode, MethodBase method)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (method is DynamicMethod)
			{
				il.Emit(opcode, (object)method);
			}
			else
			{
				il.Emit(opcode, il.Import(method));
			}
		}

		public static void Emit(this ILProcessor il, OpCode opcode, Type type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			il.Emit(opcode, il.Import(type));
		}

		public static void Emit(this ILProcessor il, OpCode opcode, MemberInfo member)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if ((object)member == null)
			{
				throw new ArgumentNullException("member");
			}
			if (!(member is FieldInfo field))
			{
				if (!(member is MethodBase method))
				{
					if (!(member is Type type))
					{
						throw new NotSupportedException("Unsupported member type " + member.GetType().FullName);
					}
					il.Emit(opcode, type);
				}
				else
				{
					il.Emit(opcode, method);
				}
			}
			else
			{
				il.Emit(opcode, field);
			}
		}

		public static void Emit(this ILProcessor il, OpCode opcode, object operand)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			il.Append(il.Create(opcode, operand));
		}

		public static TypeDefinition SafeResolve(this TypeReference r)
		{
			try
			{
				return r.Resolve();
			}
			catch
			{
				return null;
			}
		}

		public static FieldDefinition SafeResolve(this FieldReference r)
		{
			try
			{
				return r.Resolve();
			}
			catch
			{
				return null;
			}
		}

		public static MethodDefinition SafeResolve(this MethodReference r)
		{
			try
			{
				return r.Resolve();
			}
			catch
			{
				return null;
			}
		}

		public static PropertyDefinition SafeResolve(this PropertyReference r)
		{
			try
			{
				return r.Resolve();
			}
			catch
			{
				return null;
			}
		}

		public static CustomAttribute GetCustomAttribute(this ICustomAttributeProvider cap, string attribute)
		{
			//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 (cap == null || !cap.HasCustomAttributes)
			{
				return null;
			}
			Enumerator<CustomAttribute> enumerator = cap.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current = enumerator.Current;
					if (((MemberReference)current.AttributeType).FullName == attribute)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		public static bool HasCustomAttribute(this ICustomAttributeProvider cap, string attribute)
		{
			return cap.GetCustomAttribute(attribute) != null;
		}

		public static int GetInt(this Instruction instr)
		{
			//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_0007: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			OpCode opCode = instr.OpCode;
			if (opCode == OpCodes.Ldc_I4_M1)
			{
				return -1;
			}
			if (opCode == OpCodes.Ldc_I4_0)
			{
				return 0;
			}
			if (opCode == OpCodes.Ldc_I4_1)
			{
				return 1;
			}
			if (opCode == OpCodes.Ldc_I4_2)
			{
				return 2;
			}
			if (opCode == OpCodes.Ldc_I4_3)
			{
				return 3;
			}
			if (opCode == OpCodes.Ldc_I4_4)
			{
				return 4;
			}
			if (opCode == OpCodes.Ldc_I4_5)
			{
				return 5;
			}
			if (opCode == OpCodes.Ldc_I4_6)
			{
				return 6;
			}
			if (opCode == OpCodes.Ldc_I4_7)
			{
				return 7;
			}
			if (opCode == OpCodes.Ldc_I4_8)
			{
				return 8;
			}
			if (opCode == OpCodes.Ldc_I4_S)
			{
				return (sbyte)instr.Operand;
			}
			return (int)instr.Operand;
		}

		public static int? GetIntOrNull(this Instruction instr)
		{
			//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_0007: 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_001b: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			OpCode opCode = instr.OpCode;
			if (opCode == OpCodes.Ldc_I4_M1)
			{
				return -1;
			}
			if (opCode == OpCodes.Ldc_I4_0)
			{
				return 0;
			}
			if (opCode == OpCodes.Ldc_I4_1)
			{
				return 1;
			}
			if (opCode == OpCodes.Ldc_I4_2)
			{
				return 2;
			}
			if (opCode == OpCodes.Ldc_I4_3)
			{
				return 3;
			}
			if (opCode == OpCodes.Ldc_I4_4)
			{
				return 4;
			}
			if (opCode == OpCodes.Ldc_I4_5)
			{
				return 5;
			}
			if (opCode == OpCodes.Ldc_I4_6)
			{
				return 6;
			}
			if (opCode == OpCodes.Ldc_I4_7)
			{
				return 7;
			}
			if (opCode == OpCodes.Ldc_I4_8)
			{
				return 8;
			}
			if (opCode == OpCodes.Ldc_I4_S)
			{
				return (sbyte)instr.Operand;
			}
			if (opCode == OpCodes.Ldc_I4)
			{
				return (int)instr.Operand;
			}
			return null;
		}

		public static bool IsBaseMethodCall(this MethodBody body, MethodReference called)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition method = body.Method;
			if (called == null)
			{
				return false;
			}
			TypeReference val = ((MemberReference)called).DeclaringType;
			while (val is TypeSpecification)
			{
				val = ((TypeSpecification)val).ElementType;
			}
			string patchFullName = ((MemberReference)(object)val).GetPatchFullName();
			bool flag = false;
			try
			{
				TypeDefinition val2 = method.DeclaringType;
				while ((val2 = val2.BaseType?.SafeResolve()) != null)
				{
					if (((MemberReference)(object)val2).GetPatchFullName() == patchFullName)
					{
						flag = true;
						break;
					}
				}
			}
			catch
			{
				flag = ((MemberReference)(object)method.DeclaringType).GetPatchFullName() == patchFullName;
			}
			if (!flag)
			{
				return false;
			}
			return true;
		}

		public static bool IsCallvirt(this MethodReference method)
		{
			if (!method.HasThis)
			{
				return false;
			}
			if (((MemberReference)method).DeclaringType.IsValueType)
			{
				return false;
			}
			return true;
		}

		public static bool IsStruct(this TypeReference type)
		{
			if (!type.IsValueType)
			{
				return false;
			}
			if (type.IsPrimitive)
			{
				return false;
			}
			return true;
		}

		public static OpCode ToLongOp(this OpCode op)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected I4, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected I4, but got Unknown
			//IL_00a0: 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)
			string name = Enum.GetName(t_Code, ((OpCode)(ref op)).Code);
			if (!name.EndsWith("_S", StringComparison.Ordinal))
			{
				return op;
			}
			lock (_ToLongOp)
			{
				if (_ToLongOp.TryGetValue((int)((OpCode)(ref op)).Code, out var value))
				{
					return value;
				}
				return _ToLongOp[(int)((OpCode)(ref op)).Code] = (OpCode)(((??)(OpCode?)t_OpCodes.GetField(name.Substring(0, name.Length - 2))?.GetValue(null)) ?? op);
			}
		}

		public static OpCode ToShortOp(this OpCode op)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected I4, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			string name = Enum.GetName(t_Code, ((OpCode)(ref op)).Code);
			if (name.EndsWith("_S", StringComparison.Ordinal))
			{
				return op;
			}
			lock (_ToShortOp)
			{
				if (_ToShortOp.TryGetValue((int)((OpCode)(ref op)).Code, out var value))
				{
					return value;
				}
				return _ToShortOp[(int)((OpCode)(ref op)).Code] = (OpCode)(((??)(OpCode?)t_OpCodes.GetField(name + "_S")?.GetValue(null)) ?? op);
			}
		}

		public static void RecalculateILOffsets(this MethodDefinition method)
		{
			if (method.HasBody)
			{
				int num = 0;
				for (int i = 0; i < method.Body.Instructions.Count; i++)
				{
					Instruction val = method.Body.Instructions[i];
					val.Offset = num;
					num += val.GetSize();
				}
			}
		}

		public static void FixShortLongOps(this MethodDefinition method)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (!method.HasBody)
			{
				return;
			}
			for (int i = 0; i < method.Body.Instructions.Count; i++)
			{
				Instruction val = method.Body.Instructions[i];
				if (val.Operand is Instruction)
				{
					val.OpCode = val.OpCode.ToLongOp();
				}
			}
			method.RecalculateILOffsets();
			bool flag;
			do
			{
				flag = false;
				for (int j = 0; j < method.Body.Instructions.Count; j++)
				{
					Instruction val2 = method.Body.Instructions[j];
					object operand = val2.Operand;
					Instruction val3 = (Instruction)((operand is Instruction) ? operand : null);
					if (val3 != null)
					{
						int num = val3.Offset - (val2.Offset + val2.GetSize());
						if (num == (sbyte)num)
						{
							OpCode opCode = val2.OpCode;
							val2.OpCode = val2.OpCode.ToShortOp();
							flag = opCode != val2.OpCode;
						}
					}
				}
			}
			while (flag);
		}

		public static bool Is(this MemberInfo minfo, MemberReference mref)
		{
			return mref.Is(minfo);
		}

		public static bool Is(this MemberReference mref, MemberInfo minfo)
		{
			if (mref == null)
			{
				return false;
			}
			TypeReference val = mref.DeclaringType;
			if (((val != null) ? ((MemberReference)val).FullName : null) == "<Module>")
			{
				val = null;
			}
			GenericParameter val2 = (GenericParameter)(object)((mref is GenericParameter) ? mref : null);
			if (val2 != null)
			{
				if (!(minfo is Type type))
				{
					return false;
				}
				if (!type.IsGenericParameter)
				{
					IGenericParameterProvider owner = val2.Owner;
					IGenericInstance val3 = (IGenericInstance)(object)((owner is IGenericInstance) ? owner : null);
					if (val3 != null)
					{
						return ((MemberReference)(object)val3.GenericArguments[val2.Position]).Is(type);
					}
					return false;
				}
				return val2.Position == type.GenericParameterPosition;
			}
			if ((object)minfo.DeclaringType != null)
			{
				if (val == null)
				{
					return false;
				}
				Type type2 = minfo.DeclaringType;
				if (minfo is Type && type2.IsGenericType && !type2.IsGenericTypeDefinition)
				{
					type2 = type2.GetGenericTypeDefinition();
				}
				if (!((MemberReference)(object)val).Is(type2))
				{
					return false;
				}
			}
			else if (val != null)
			{
				return false;
			}
			if (!(mref is TypeSpecification) && mref.Name != minfo.Name)
			{
				return false;
			}
			TypeReference val4 = (TypeReference)(object)((mref is TypeReference) ? mref : null);
			if (val4 != null)
			{
				if (!(minfo is Type type3))
				{
					return false;
				}
				if (type3.IsGenericParameter)
				{
					return false;
				}
				GenericInstanceType val5 = (GenericInstanceType)(object)((mref is GenericInstanceType) ? mref : null);
				if (val5 != null)
				{
					if (!type3.IsGenericType)
					{
						return false;
					}
					Collection<TypeReference> genericArguments = val5.GenericArguments;
					Type[] genericArguments2 = type3.GetGenericArguments();
					if (genericArguments.Count != genericArguments2.Length)
					{
						return false;
					}
					for (int i = 0; i < genericArguments.Count; i++)
					{
						if (!((MemberReference)(object)genericArguments[i]).Is(genericArguments2[i]))
						{
							return false;
						}
					}
					return ((MemberReference)(object)((TypeSpecification)val5).ElementType).Is(type3.GetGenericTypeDefinition());
				}
				if (val4.HasGenericParameters)
				{
					if (!type3.IsGenericType)
					{
						return false;
					}
					Collection<GenericParameter> genericParameters = val4.GenericParameters;
					Type[] genericArguments3 = type3.GetGenericArguments();
					if (genericParameters.Count != genericArguments3.Length)
					{
						return false;
					}
					for (int j = 0; j < genericParameters.Count; j++)
					{
						if (!((MemberReference)(object)genericParameters[j]).Is(genericArguments3[j]))
						{
							return false;
						}
					}
				}
				else if (type3.IsGenericType)
				{
					return false;
				}
				ArrayType val6 = (ArrayType)(object)((mref is ArrayType) ? mref : null);
				if (val6 != null)
				{
					if (!type3.IsArray)
					{
						return false;
					}
					if (val6.Dimensions.Count == type3.GetArrayRank())
					{
						return ((MemberReference)(object)((TypeSpecification)val6).ElementType).Is(type3.GetElementType());
					}
					return false;
				}
				ByReferenceType val7 = (ByReferenceType)(object)((mref is ByReferenceType) ? mref : null);
				if (val7 != null)
				{
					if (!type3.IsByRef)
					{
						return false;
					}
					return ((MemberReference)(object)((TypeSpecification)val7).ElementType).Is(type3.GetElementType());
				}
				PointerType val8 = (PointerType)(object)((mref is PointerType) ? mref : null);
				if (val8 != null)
				{
					if (!type3.IsPointer)
					{
						return false;
					}
					return ((MemberReference)(object)((TypeSpecification)val8).ElementType).Is(type3.GetElementType());
				}
				TypeSpecification val9 = (TypeSpecification)(object)((mref is TypeSpecification) ? mref : null);
				if (val9 != null)
				{
					return ((MemberReference)(object)val9.ElementType).Is(type3.HasElementType ? type3.GetElementType() : type3);
				}
				if (val != null)
				{
					return mref.Name == type3.Name;
				}
				return mref.FullName == MultiTargetShims.Replace(type3.FullName, "+", "/", StringComparison.Ordinal);
			}
			if (minfo is Type)
			{
				return false;
			}
			MethodReference methodRef = (MethodReference)(object)((mref is MethodReference) ? mref : null);
			if (methodRef != null)
			{
				if (!(minfo is MethodBase methodBase))
				{
					return false;
				}
				Collection<ParameterDefinition> parameters = methodRef.Parameters;
				ParameterInfo[] parameters2 = methodBase.GetParameters();
				if (parameters.Count != parameters2.Length)
				{
					return false;
				}
				GenericInstanceMethod val10 = (GenericInstanceMethod)(object)((mref is GenericInstanceMethod) ? mref : null);
				if (val10 != null)
				{
					if (!methodBase.IsGenericMethod)
					{
						return false;
					}
					Collection<TypeReference> genericArguments4 = val10.GenericArguments;
					Type[] genericArguments5 = methodBase.GetGenericArguments();
					if (genericArguments4.Count != genericArguments5.Length)
					{
						return false;
					}
					for (int k = 0; k < genericArguments4.Count; k++)
					{
						if (!((MemberReference)(object)genericArguments4[k]).Is(genericArguments5[k]))
						{
							return false;
						}
					}
					return ((MemberReference)(object)((MethodSpecification)val10).ElementMethod).Is((methodBase as MethodInfo)?.GetGenericMethodDefinition() ?? methodBase);
				}
				if (methodRef.HasGenericParameters)
				{
					if (!methodBase.IsGenericMethod)
					{
						return false;
					}
					Collection<GenericParameter> genericParameters2 = methodRef.GenericParameters;
					Type[] genericArguments6 = methodBase.GetGenericArguments();
					if (genericParameters2.Count != genericArguments6.Length)
					{
						return false;
					}
					for (int l = 0; l < genericParameters2.Count; l++)
					{
						if (!((MemberReference)(object)genericParameters2[l]).Is(genericArguments6[l]))
						{
							return false;
						}
					}
				}
				else if (methodBase.IsGenericMethod)
				{
					return false;
				}
				Relinker relinker = null;
				relinker = delegate(IMetadataTokenProvider paramMemberRef, IGenericParameterProvider ctx)
				{
					TypeReference val15 = (TypeReference)(object)((paramMemberRef is TypeReference) ? paramMemberRef : null);
					return (IMetadataTokenProvider)((val15 == null) ? ((object)paramMemberRef) : ((object)ResolveParameter(val15)));
				};
				if (!((MemberReference)(object)methodRef.ReturnType.Relink(relinker, null)).Is((methodBase as MethodInfo)?.ReturnType ?? typeof(void)) && !((MemberReference)(object)methodRef.ReturnType).Is((methodBase as MethodInfo)?.ReturnType ?? typeof(void)))
				{
					return false;
				}
				for (int m = 0; m < parameters.Count; m++)
				{
					if (!((MemberReference)(object)((ParameterReference)parameters[m]).ParameterType.Relink(relinker, null)).Is(parameters2[m].ParameterType) && !((MemberReference)(object)((ParameterReference)parameters[m]).ParameterType).Is(parameters2[m].ParameterType))
					{
						return false;
					}
				}
				return true;
			}
			if (minfo is MethodInfo)
			{
				return false;
			}
			if (mref is FieldReference != minfo is FieldInfo)
			{
				return false;
			}
			if (mref is PropertyReference != minfo is PropertyInfo)
			{
				return false;
			}
			if (mref is EventReference != minfo is EventInfo)
			{
				return false;
			}
			return true;
			TypeReference ResolveParameter(TypeReference paramTypeRef)
			{
				GenericParameter val11 = (GenericParameter)(object)((paramTypeRef is GenericParameter) ? paramTypeRef : null);
				if (val11 != null)
				{
					if (val11.Owner is MethodReference)
					{
						MethodReference obj = methodRef;
						GenericInstanceMethod val12 = (GenericInstanceMethod)(object)((obj is GenericInstanceMethod) ? obj : null);
						if (val12 != null)
						{
							return val12.GenericArguments[val11.Position];
						}
					}
					IGenericParameterProvider owner2 = val11.Owner;
					TypeReference val13 = (TypeReference)(object)((owner2 is TypeReference) ? owner2 : null);
					if (val13 != null)
					{
						TypeReference declaringType = ((MemberReference)methodRef).DeclaringType;
						GenericInstanceType val14 = (GenericInstanceType)(object)((declaringType is GenericInstanceType) ? declaringType : null);
						if (val14 != null && ((MemberReference)val13).FullName == ((MemberReference)((TypeSpecification)val14).ElementType).FullName)
						{
							return val14.GenericArguments[val11.Position];
						}
					}
					return paramTypeRef;
				}
				if (paramTypeRef == ((MemberReference)methodRef).DeclaringType.GetElementType())
				{
					return ((MemberReference)methodRef).DeclaringType;
				}
				return paramTypeRef;
			}
		}

		public static IMetadataTokenProvider ImportReference(this ModuleDefinition mod, IMetadataTokenProvider mtp)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (mtp is TypeReference)
			{
				return (IMetadataTokenProvider)(object)mod.ImportReference((TypeReference)mtp);
			}
			if (mtp is FieldReference)
			{
				return (IMetadataTokenProvider)(object)mod.ImportReference((FieldReference)mtp);
			}
			if (mtp is MethodReference)
			{
				return (IMetadataTokenProvider)(object)mod.ImportReference((MethodReference)mtp);
			}
			return mtp;
		}

		public static void AddRange<T>(this Collection<T> list, IEnumerable<T> other)
		{
			foreach (T item in other)
			{
				list.Add(item);
			}
		}

		public static void AddRange(this IDictionary dict, IDictionary other)
		{
			foreach (DictionaryEntry item in other)
			{
				dict.Add(item.Key, item.Value);
			}
		}

		public static void AddRange<K, V>(this IDictionary<K, V> dict, IDictionary<K, V> other)
		{
			foreach (KeyValuePair<K, V> item in other)
			{
				dict.Add(item.Key, item.Value);
			}
		}

		public static void AddRange<K, V>(this Dictionary<K, V> dict, Dictionary<K, V> other)
		{
			foreach (KeyValuePair<K, V> item in other)
			{
				dict.Add(item.Key, item.Value);
			}
		}

		public static void InsertRange<T>(this Collection<T> list, int index, IEnumerable<T> other)
		{
			foreach (T item in other)
			{
				list.Insert(index++, item);
			}
		}

		public static bool IsCompatible(this Type type, Type other)
		{
			if (!type._IsCompatible(other))
			{
				return other._IsCompatible(type);
			}
			return true;
		}

		private static bool _IsCompatible(this Type type, Type other)
		{
			if ((object)type == other)
			{
				return true;
			}
			if (type.IsAssignableFrom(other))
			{
				return true;
			}
			if (other.IsEnum && type.IsCompatible(Enum.GetUnderlyingType(other)))
			{
				return true;
			}
			if ((other.IsPointer || other.IsByRef) && (object)type == typeof(IntPtr))
			{
				return true;
			}
			return false;
		}

		public static T GetDeclaredMember<T>(this T member) where T : MemberInfo
		{
			if ((object)member.DeclaringType == member.ReflectedType)
			{
				return member;
			}
			int metadataToken = member.MetadataToken;
			MemberInfo[] members = member.DeclaringType.GetMembers((BindingFlags)(-1));
			foreach (MemberInfo memberInfo in members)
			{
				if (memberInfo.MetadataToken == metadataToken)
				{
					return (T)memberInfo;
				}
			}
			return member;
		}

		public unsafe static void SetMonoCorlibInternal(this Assembly asm, bool value)
		{
			if ((object)Type.GetType("Mono.Runtime") == null)
			{
				return;
			}
			Type type = asm?.GetType();
			if ((object)type == null)
			{
				return;
			}
			FieldInfo value2;
			lock (fmap_mono_assembly)
			{
				if (!fmap_mono_assembly.TryGetValue(type, out value2))
				{
					value2 = type.GetField("_mono_assembly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("dynamic_assembly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					fmap_mono_assembly[type] = value2;
				}
			}
			if ((object)value2 == null)
			{
				return;
			}
			AssemblyName assemblyName = new AssemblyName(asm.FullName);
			lock (ReflectionHelper.AssemblyCache)
			{
				WeakReference value3 = new WeakReference(asm);
				ReflectionHelper.AssemblyCache[asm.GetRuntimeHashedFullName()] = value3;
				ReflectionHelper.AssemblyCache[assemblyName.FullName] = value3;
				ReflectionHelper.AssemblyCache[assemblyName.Name] = value3;
			}
			long num = 0L;
			object value4 = value2.GetValue(asm);
			if (!(value4 is IntPtr intPtr))
			{
				if (value4 is UIntPtr uIntPtr)
				{
					num = (long)(ulong)uIntPtr;
				}
			}
			else
			{
				num = (long)intPtr;
			}
			int num2 = IntPtr.Size + IntPtr.Size + IntPtr.Size + IntPtr.Size + IntPtr.Size + IntPtr.Size + 20 + 4 + 4 + 4 + (_MonoAssemblyNameHasArch ? ((!(typeof(object).Assembly.GetName().Name == "System.Private.CoreLib")) ? ((IntPtr.Size == 4) ? 12 : 16) : ((IntPtr.Size == 4) ? 20 : 24)) : ((typeof(object).Assembly.GetName().Name == "System.Private.CoreLib") ? 16 : 8)) + IntPtr.Size + IntPtr.Size + 1 + 1 + 1;
			byte* ptr = (byte*)(num + num2);
			*ptr = (byte)(value ? 1 : 0);
		}

		public static bool IsDynamicMethod(this MethodBase method)
		{
			if ((object)_RTDynamicMethod != null)
			{
				if (!(method is DynamicMethod))
				{
					return (object)method.GetType() == _RTDynamicMethod;
				}
				return true;
			}
			if (method is DynamicMethod)
			{
				return true;
			}
			if (method.MetadataToken != 0 || !method.IsStatic || !method.IsPublic || (method.Attributes & MethodAttributes.PrivateScope) != 0)
			{
				return false;
			}
			MethodInfo[] methods = method.DeclaringType.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if ((object)method == methodInfo)
				{
					return false;
				}
			}
			return true;
		}

		public static object SafeGetTarget(this WeakReference weak)
		{
			try
			{
				return weak.Target;
			}
			catch (InvalidOperationException)
			{
				return null;
			}
		}

		public static bool SafeGetIsAlive(this WeakReference weak)
		{
			try
			{
				return weak.IsAlive;
			}
			catch (InvalidOperationException)
			{
				return false;
			}
		}

		public static T CreateDelegate<T>(this MethodBase method) where T : Delegate
		{
			return (T)method.CreateDelegate(typeof(T), null);
		}

		public static T CreateDelegate<T>(this MethodBase method, object target) where T : Delegate
		{
			return (T)method.CreateDelegate(typeof(T), target);
		}

		public static Delegate CreateDelegate(this MethodBase method, Type delegateType)
		{
			return method.CreateDelegate(delegateType, null);
		}

		public static Delegate CreateDelegate(this MethodBase method, Type delegateType, object target)
		{
			if (!typeof(Delegate).IsAssignableFrom(delegateType))
			{
				throw new ArgumentException("Type argument must be a delegate type!");
			}
			if (method is DynamicMethod dynamicMethod)
			{
				return dynamicMethod.CreateDelegate(delegateType, target);
			}
			RuntimeMethodHandle methodHandle = method.MethodHandle;
			RuntimeHelpers.PrepareMethod(methodHandle);
			IntPtr functionPointer = methodHandle.GetFunctionPointer();
			return (Delegate)Activator.CreateInstance(delegateType, target, functionPointer);
		}

		public static MethodDefinition FindMethod(this TypeDefinition type, string id, bool simple = true)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<MethodDefinition> enumerator;
			if (simple && !MultiTargetShims.Contains(id, " ", StringComparison.Ordinal))
			{
				enumerator = type.Methods.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						MethodDefinition current = enumerator.Current;
						if (((MethodReference)(object)current).GetID(null, null, withType: true, simple: true) == id)
						{
							return current;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				enumerator = type.Methods.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						MethodDefinition current2 = enumerator.Current;
						if (((MethodReference)(object)current2).GetID(null, null, withType: false, simple: true) == id)
						{
							return current2;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current3 = enumerator.Current;
					if (((MethodReference)(object)current3).GetID() == id)
					{
						return current3;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current4 = enumerator.Current;
					if (((MethodReference)(object)current4).GetID(null, null, withType: false) == id)
					{
						return current4;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		public static MethodDefinition FindMethodDeep(this TypeDefinition type, string id, bool simple = true)
		{
			MethodDefinition obj = type.FindMethod(id, simple);
			if (obj == null)
			{
				TypeReference baseType = type.BaseType;
				if (baseType == null)
				{
					return null;
				}
				TypeDefinition obj2 = baseType.Resolve();
				if (obj2 == null)
				{
					return null;
				}
				obj = obj2.FindMethodDeep(id, simple);
			}
			return obj;
		}

		public static MethodInfo FindMethod(this Type type, string id, bool simple = true)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array;
			if (simple && !MultiTargetShims.Contains(id, " ", StringComparison.Ordinal))
			{
				array = methods;
				foreach (MethodInfo methodInfo in array)
				{
					if (methodInfo.GetID(null, null, withType: true, proxyMethod: false, simple: true) == id)
					{
						return methodInfo;
					}
				}
				array = methods;
				foreach (MethodInfo methodInfo2 in array)
				{
					if (methodInfo2.GetID(null, null, withType: false, proxyMethod: false, simple: true) == id)
					{
						return methodInfo2;
					}
				}
			}
			array = methods;
			foreach (MethodInfo methodInfo3 in array)
			{
				if (methodInfo3.GetID(null, null, withType: true, proxyMethod: false, simple: false) == id)
				{
					return methodInfo3;
				}
			}
			array = methods;
			foreach (MethodInfo methodInfo4 in array)
			{
				if (methodInfo4.GetID(null, null, withType: false, proxyMethod: false, simple: false) == id)
				{
					return methodInfo4;
				}
			}
			return null;
		}

		public static MethodInfo FindMethodDeep(this Type type, string id, bool simple = true)
		{
			MethodInfo methodInfo = type.FindMethod(id, simple);
			if ((object)methodInfo == null)
			{
				Type? baseType = type.BaseType;
				if ((object)baseType == null)
				{
					return null;
				}
				methodInfo = baseType.FindMethodDeep(id, simple);
			}
			return methodInfo;
		}

		public static PropertyDefinition FindProperty(this TypeDefinition type, string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<PropertyDefinition> enumerator = type.Properties.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					PropertyDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == name)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		public static PropertyDefinition FindPropertyDeep(this TypeDefinition type, string name)
		{
			PropertyDefinition obj = type.FindProperty(name);
			if (obj == null)
			{
				TypeReference baseType = type.BaseType;
				if (baseType == null)
				{
					return null;
				}
				TypeDefinition obj2 = baseType.Resolve();
				if (obj2 == null)
				{
					return null;
				}
				obj = obj2.FindPropertyDeep(name);
			}
			return obj;
		}

		public static FieldDefinition FindField(this TypeDefinition type, string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<FieldDefinition> enumerator = type.Fields.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					FieldDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == name)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		public static FieldDefinition FindFieldDeep(this TypeDefinition type, string name)
		{
			FieldDefinition obj = type.FindField(name);
			if (obj == null)
			{
				TypeReference baseType = type.BaseType;
				if (baseType == null)
				{
					return null;
				}
				TypeDefinition obj2 = baseType.Resolve();
				if (obj2 == null)
				{
					return null;
				}
				obj = obj2.FindFieldDeep(name);
			}
			return obj;
		}

		public static EventDefinition FindEvent(this TypeDefinition type, string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<EventDefinition> enumerator = type.Events.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					EventDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == name)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		public static EventDefinition FindEventDeep(this TypeDefinition type, string name)
		{
			EventDefinition obj = type.FindEvent(name);
			if (obj == null)
			{
				TypeReference baseType = type.BaseType;
				if (baseType == null)
				{
					return null;
				}
				TypeDefinition obj2 = baseType.Resolve();
				if (obj2 == null)
				{
					return null;
				}
				obj = obj2.FindEventDeep(name);
			}
			return obj;
		}

		public static string GetID(this MethodReference method, string name = null, string type = null, bool withType = true, bool simple = false)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (simple)
			{
				if (withType && (type != null || ((MemberReference)method).DeclaringType != null))
				{
					stringBuilder.Append(type ?? ((MemberReference)(object)((MemberReference)method).DeclaringType).GetPatchFullName()).Append("::");
				}
				stringBuilder.Append(name ?? ((MemberReference)method).Name);
				return stringBuilder.ToString();
			}
			stringBuilder.Append(((MemberReference)(object)method.ReturnType).GetPatchFullName()).Append(" ");
			if (withType && (type != null || ((MemberReference)method).DeclaringType != null))
			{
				stringBuilder.Append(type ?? ((MemberReference)(object)((MemberReference)method).DeclaringType).GetPatchFullName()).Append("::");
			}
			stringBuilder.Append(name ?? ((MemberReference)method).Name);
			GenericInstanceMethod val = (GenericInstanceMethod)(object)((method is GenericInstanceMethod) ? method : null);
			if (val != null && val.GenericArguments.Count != 0)
			{
				stringBuilder.Append("<");
				Collection<TypeReference> genericArguments = val.GenericArguments;
				for (int i = 0; i < genericArguments.Count; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(",");
					}
					stringBuilder.Append(((MemberReference)(object)genericArguments[i]).GetPatchFullName());
				}
				stringBuilder.Append(">");
			}
			else if (method.GenericParameters.Count != 0)
			{
				stringBuilder.Append("<");
				Collection<GenericParameter> genericParameters = method.GenericParameters;
				for (int j = 0; j < genericParameters.Count; j++)
				{
					if (j > 0)
					{
						stringBuilder.Append(",");
					}
					stringBuilder.Append(((MemberReference)genericParameters[j]).Name);
				}
				stringBuilder.Append(">");
			}
			stringBuilder.Append("(");
			if (method.HasParameters)
			{
				Collection<ParameterDefinition> parameters = method.Parameters;
				for (int k = 0; k < parameters.Count; k++)
				{
					ParameterDefinition val2 = parameters[k];
					if (k > 0)
					{
						stringBuilder.Append(",");
					}
					if (((ParameterReference)val2).ParameterType.IsSentinel)
					{
						stringBuilder.Append("...,");
					}
					stringBuilder.Append(((MemberReference)(object)((ParameterReference)val2).ParameterType).GetPatchFullName());
				}
			}
			stringBuilder.Append(")");
			return stringBuilder.ToString();
		}

		public static string GetID(this CallSite method)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(((MemberReference)(object)method.ReturnType).GetPatchFullName()).Append(" ");
			stringBuilder.Append("(");
			if (method.HasParameters)
			{
				Collection<ParameterDefinition> parameters = method.Parameters;
				for (int i = 0; i < parameters.Count; i++)
				{
					ParameterDefinition val = parameters[i];
					if (i > 0)
					{
						stringBuilder.Append(",");
					}
					if (((ParameterReference)val).ParameterType.IsSentinel)
					{
						stringBuilder.Append("...,");
					}
					stringBuilder.Append(((MemberReference)(object)((ParameterReference)val).ParameterType).GetPatchFullName());
				}
			}
			stringBuilder.Append(")");
			return stringBuilder.ToString();
		}

		public static string GetID(this MethodBase method, string name = null, string type = null, bool withType = true, bool proxyMethod = false, bool simple = false)
		{
			while (method is MethodInfo && method.IsGenericMethod && !method.IsGenericMethodDefinition)
			{
				method = ((MethodInfo)method).GetGenericMethodDefinition();
			}
			StringBuilder stringBuilder = new StringBuilder();
			if (simple)
			{
				if (withType && (type != null || (object)method.DeclaringType != null))
				{
					stringBuilder.Append(type ?? method.DeclaringType.FullName).Append("::");
				}
				stringBuilder.Append(name ?? method.Name);
				return stringBuilder.ToString();
			}
			stringBuilder.Append((method as MethodInfo)?.ReturnType?.FullName ?? "System.Void").Append(" ");
			if (withType && (type != null || (object)method.DeclaringType != null))
			{
				stringBuilder.Append(type ?? MultiTargetShims.Replace(method.DeclaringType.FullName, "+", "/", StringComparison.Ordinal)).Append("::");
			}
			stringBuilder.Append(name ?? method.Name);
			if (method.ContainsGenericParameters)
			{
				stringBuilder.Append("<");
				Type[] genericArguments = method.GetGenericArguments();
				for (int i = 0; i < genericArguments.Length; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(",");
					}
					stringBuilder.Append(genericArguments[i].Name);
				}
				stringBuilder.Append(">");
			}
			stringBuilder.Append("(");
			ParameterInfo[] parameters = method.GetParameters();
			for (int j = (proxyMethod ? 1 : 0); j < parameters.Length; j++)
			{
				ParameterInfo parameterInfo = parameters[j];
				if (j > (proxyMethod ? 1 : 0))
				{
					stringBuilder.Append(",");
				}
				bool flag;
				try
				{
					flag = parameterInfo.GetCustomAttributes(t_ParamArrayAttribute, inherit: false).Length != 0;
				}
				catch (NotSupportedException)
				{
					flag = false;
				}
				if (flag)
				{
					stringBuilder.Append("...,");
				}
				stringBuilder.Append(parameterInfo.ParameterType.FullName);
			}
			stringBuilder.Append(")");
			return stringBuilder.ToString();
		}

		public static string GetPatchName(this MemberReference mr)
		{
			MemberReference obj = ((mr is ICustomAttributeProvider) ? mr : null);
			return ((obj != null) ? ((ICustomAttributeProvider)(object)obj).GetPatchName() : null) ?? mr.Name;
		}

		public static string GetPatchFullName(this MemberReference mr)
		{
			MemberReference obj = ((mr is ICustomAttributeProvider) ? mr : null);
			return ((obj != null) ? ((ICustomAttributeProvider)(object)obj).GetPatchFullName(mr) : null) ?? mr.FullName;
		}

		private static string GetPatchName(this ICustomAttributeProvider cap)
		{
			//IL_004e: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			CustomAttribute customAttribute = cap.GetCustomAttribute("MonoMod.MonoModPatch");
			string text;
			if (customAttribute != null)
			{
				CustomAttributeArgument val = customAttribute.ConstructorArguments[0];
				text = (string)((CustomAttributeArgument)(ref val)).Value;
				int num = text.LastIndexOf('.');
				if (num != -1 && num != text.Length - 1)
				{
					text = text.Substring(num + 1);
				}
				return text;
			}
			text = ((MemberReference)cap).Name;
			if (!text.StartsWith("patch_", StringComparison.Ordinal))
			{
				return text;
			}
			return text.Substring(6);
		}

		private static string GetPatchFullName(this ICustomAttributeProvider cap, MemberReference mr)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Expected O, but got Unknown
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			TypeReference val = (TypeReference)(object)((cap is TypeReference) ? cap : null);
			if (val != null)
			{
				CustomAttribute customAttribute = cap.GetCustomAttribute("MonoMod.MonoModPatch");
				string text;
				if (customAttribute != null)
				{
					CustomAttributeArgument val2 = customAttribute.ConstructorArguments[0];
					text = (string)((CustomAttributeArgument)(ref val2)).Value;
				}
				else
				{
					text = ((MemberReference)cap).Name;
					text = (text.StartsWith("patch_", StringComparison.Ordinal) ? text.Substring(6) : text);
				}
				if (text.StartsWith("global::", StringComparison.Ordinal))
				{
					text = text.Substring(8);
				}
				else if (!MultiTargetShims.Contains(text, ".", StringComparison.Ordinal) && !MultiTargetShims.Contains(text, "/", StringComparison.Ordinal))
				{
					if (!string.IsNullOrEmpty(val.Namespace))
					{
						text = val.Namespace + "." + text;
					}
					else if (val.IsNested)
					{
						text = ((MemberReference)(object)((MemberReference)val).DeclaringType).GetPatchFullName() + "/" + text;
					}
				}
				if (mr is TypeSpecification)
				{
					List<TypeSpecification> list = new List<TypeSpecification>();
					TypeSpecification val3 = (TypeSpecification)mr;
					TypeReference elementType;
					do
					{
						list.Add(val3);
						elementType = val3.ElementType;
					}
					while ((val3 = (TypeSpecification)(object)((elementType is TypeSpecification) ? elementType : null)) != null);
					StringBuilder stringBuilder = new StringBuilder(text.Length + list.Count * 4);
					stringBuilder.Append(text);
					for (int num = list.Count - 1; num > -1; num--)
					{
						val3 = list[num];
						if (((TypeReference)val3).IsByReference)
						{
							stringBuilder.Append("&");
						}
						else if (((TypeReference)val3).IsPointer)
						{
							stringBuilder.Append("*");
						}
						else if (!((TypeReference)val3).IsPinned && !((TypeReference)val3).IsSentinel)
						{
							if (((TypeReference)val3).IsArray)
							{
								ArrayType val4 = (ArrayType)val3;
								if (val4.IsVector)
								{
									stringBuilder.Append("[]");
								}
								else
								{
									stringBuilder.Append("[");
									for (int i = 0; i < val4.Dimensions.Count; i++)
									{
										if (i > 0)
										{
											stringBuilder.Append(",");
										}
										ArrayDimension val5 = val4.Dimensions[i];
										stringBuilder.Append(((object)(ArrayDimension)(ref val5)).ToString());
									}
									stringBuilder.Append("]");
								}
							}
							else if (((TypeReference)val3).IsRequiredModifier)
							{
								stringBuilder.Append("modreq(").Append(((RequiredModifierType)val3).ModifierType).Append(")");
							}
							else if (((TypeReference)val3).IsOptionalModifier)
							{
								stringBuilder.Append("modopt(").Append(((OptionalModifierType)val3).ModifierType).Append(")");
							}
							else if (((TypeReference)val3).IsGenericInstance)
							{
								GenericInstanceType val6 = (GenericInstanceType)val3;
								stringBuilder.Append("<");
								for (int j = 0; j < val6.GenericArguments.Count; j++)
								{
									if (j > 0)
									{
										stringBuilder.Append(",");
									}
									stringBuilder.Append(((MemberReference)(object)val6.GenericArguments[j]).GetPatchFullName());
								}
								stringBuilder.Append(">");
							}
							else
							{
								if (!((TypeReference)val3).IsFunctionPointer)
								{
									throw new NotSupportedException($"MonoMod can't handle TypeSpecification: {((MemberReference)val).FullName} ({((object)val).GetType()})");
								}
								FunctionPointerType val7 = (FunctionPointerType)val3;
								stringBuilder.Append(" ").Append(((MemberReference)(object)val7.ReturnType).GetPatchFullName()).Append(" *(");
								if (val7.HasParameters)
								{
									for (int k = 0; k < val7.Parameters.Count; k++)
									{
										ParameterDefinition val8 = val7.Parameters[k];
										if (k > 0)
										{
											stringBuilder.Append(",");
										}
										if (((ParameterReference)val8).ParameterType.IsSentinel)
										{
											stringBuilder.Append("...,");
										}
										stringBuilder.Append(((MemberReference)((ParameterReference)val8).ParameterType).FullName);
									}
								}
								stringBuilder.Append(")");
							}
						}
					}
					text = stringBuilder.ToString();
				}
				return text;
			}
			FieldReference val9 = (FieldReference)(object)((cap is FieldReference) ? cap : null);
			if (val9 != null)
			{
				return ((MemberReference)(object)val9.FieldType).GetPatchFullName() + " " + ((MemberReference)(object)((MemberReference)val9).DeclaringType).GetPatchFullName() + "::" + cap.GetPatchName();
			}
			if (cap is MethodReference)
			{
				throw new InvalidOperationException("GetPatchFullName not supported on MethodReferences - use GetID instead");
			}
			throw new InvalidOperationException($"GetPatchFullName not supported on type {((object)cap).GetType()}");
		}

		public static MethodDefinition Clone(this MethodDefinition o, MethodDefinition c = null)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00bd: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			if (o == null)
			{
				return null;
			}
			if (c == null)
			{
				c = new MethodDefinition(((MemberReference)o).Name, o.Attributes, ((MethodReference)o).ReturnType);
			}
			((MemberReference)c).Name = ((MemberReference)o).Name;
			c.Attributes = o.Attributes;
			((MethodReference)c).ReturnType = ((MethodReference)o).ReturnType;
			c.DeclaringType = o.DeclaringType;
			((MemberReference)c).MetadataToken = ((MemberReference)c).MetadataToken;
			c.Body = o.Body?.Clone(c);
			c.Attributes = o.Attributes;
			c.ImplAttributes = o.ImplAttributes;
			c.PInvokeInfo = o.PInvokeInfo;
			c.IsPreserveSig = o.IsPreserveSig;
			c.IsPInvokeImpl = o.IsPInvokeImpl;
			Enumerator<GenericParameter> enumerator = ((MethodReference)o).GenericParameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					GenericParameter current = enumerator.Current;
					((MethodReference)c).GenericParameters.Add(current.Clone());
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<ParameterDefinition> enumerator2 = ((MethodReference)o).Parameters.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ParameterDefinition current2 = enumerator2.Current;
					((MethodReference)c).Parameters.Add(current2.Clone());
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Enumerator<CustomAttribute> enumerator3 = o.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					CustomAttribute current3 = enumerator3.Current;
					c.CustomAttributes.Add(current3.Clone());
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Enumerator<MethodReference> enumerator4 = o.Overrides.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					MethodReference current4 = enumerator4.Current;
					c.Overrides.Add(current4);
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
			if (c.Body != null)
			{
				Enumerator<Instruction> enumerator5 = c.Body.Instructions.GetEnumerator();
				try
				{
					while (enumerator5.MoveNext())
					{
						Instruction current5 = enumerator5.Current;
						object operand = current5.Operand;
						GenericParameter val = (GenericParameter)((operand is GenericParameter) ? operand : null);
						int num;
						if (val != null && (num = ((MethodReference)o).GenericParameters.IndexOf(val)) != -1)
						{
							current5.Operand = ((MethodReference)c).GenericParameters[num];
							continue;
						}
						object operand2 = current5.Operand;
						ParameterDefinition val2 = (ParameterDefinition)((operand2 is ParameterDefinition) ? operand2 : null);
						if (val2 != null && (num = ((MethodReference)o).Parameters.IndexOf(val2)) != -1)
						{
							current5.Operand = ((MethodReference)c).Parameters[num];
						}
					}
				}
				finally
				{
					((IDisposable)enumerator5).Dispose();
				}
			}
			return c;
		}

		public static MethodBody Clone(this MethodBody bo, MethodDefinition m)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (bo == null)
			{
				return null;
			}
			MethodBody bc = new MethodBody(m);
			bc.MaxStackSize = bo.MaxStackSize;
			bc.InitLocals = bo.InitLocals;
			bc.LocalVarToken = bo.LocalVarToken;
			bc.Instructions.AddRange(((IEnumerable<Instruction>)bo.Instructions).Select(delegate(Instruction o)
			{
				//IL_0000: 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)
				Instruction obj = Instruction.Create(OpCodes.Nop);
				obj.OpCode = o.OpCode;
				obj.Operand = o.Operand;
				obj.Offset = o.Offset;
				return obj;
			}));
			Enumerator<Instruction> enumerator = bc.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					object operand = current.Operand;
					Instruction val = (Instruction)((operand is Instruction) ? operand : null);
					if (val != null)
					{
						current.Operand = bc.Instructions[bo.Instructions.IndexOf(val)];
					}
					else if (current.Operand is Instruction[] source)
					{
						current.Operand = source.Select((Instruction i) => bc.Instructions[bo.Instructions.IndexOf(i)]).ToArray();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			bc.ExceptionHandlers.AddRange(((IEnumerable<ExceptionHandler>)bo.ExceptionHandlers).Select((Func<ExceptionHandler, ExceptionHandler>)((ExceptionHandler o) => new ExceptionHandler(o.HandlerType)
			{
				TryStart = ((o.TryStart == null) ? null : bc.Instructions[bo.Instructions.IndexOf(o.TryStart)]),
				TryEnd = ((o.TryEnd == null) ? null : bc.Instructions[bo.Instructions.IndexOf(o.TryEnd)]),
				FilterStart = ((o.FilterStart == null) ? null : bc.Instructions[bo.Instructions.IndexOf(o.FilterStart)]),
				HandlerStart = ((o.HandlerStart == null) ? null : bc.Instructions[bo.Instructions.IndexOf(o.HandlerStart)]),
				HandlerEnd = ((o.HandlerEnd == null) ? null : bc.Instructions[bo.Instructions.IndexOf(o.HandlerEnd)]),
				CatchType = o.CatchType
			})));
			bc.Variables.AddRange(((IEnumerable<VariableDefinition>)bo.Variables).Select((Func<VariableDefinition, VariableDefinition>)((VariableDefinition o) => new VariableDefinition(((VariableReference)o).VariableType))));
			m.CustomDebugInformations.AddRange((IEnumerable<CustomDebugInformation>)bo.Method.CustomDebugInformations);
			m.DebugInformation.SequencePoints.AddRange(((IEnumerable<SequencePoint>)bo.Method.DebugInformation.SequencePoints).Select((Func<SequencePoint, SequencePoint>)((SequencePoint o) => new SequencePoint(((IEnumerable<Instruction>)bc.Instructions).FirstOrDefault((Func<Instruction, bool>)((Instruction i) => i.Offset == o.Offset)), o.Document)
			{
				StartLine = o.StartLine,
				StartColumn = o.StartColumn,
				EndLine = o.EndLine,
				EndColumn = o.EndColumn
			})));
			return bc;
		}

		public static GenericParameter Update(this GenericParameter param, int position, GenericParameterType type)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			f_GenericParameter_position.SetValue(param, position);
			f_GenericParameter_type.SetValue(param, type);
			return param;
		}

		public static GenericParameter ResolveGenericParameter(this IGenericParameterProvider provider, GenericParameter orig)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0027: Expected O, but got Unknown
			if (provider is GenericParameter && ((MemberReference)(GenericParameter)provider).Name == ((MemberReference)orig).Name)
			{
				return (GenericParameter)provider;
			}
			Enumerator<GenericParameter> enumerator = provider.GenericParameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					GenericParameter current = enumerator.Current;
					if (((MemberReference)current).Name == ((MemberReference)orig).Name)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			int position = orig.Position;
			if (provider is MethodReference && orig.DeclaringMethod != null)
			{
				if (position < provider.GenericParameters.Count)
				{
					return provider.GenericParameters[position];
				}
				return orig.Clone().Update(position, (GenericParameterType)1);
			}
			if (provider is TypeReference && ((MemberReference)orig).DeclaringType != null)
			{
				if (position < provider.GenericParameters.Count)
				{
					return provider.GenericParameters[position];
				}
				return orig.Clone().Update(position, (GenericParameterType)0);
			}
			IGenericParameterProvider obj = ((provider is TypeSpecification) ? provider : null);
			object obj2 = ((obj != null) ? ((IGenericParameterProvider)(object)((TypeSpecification)obj).ElementType).ResolveGenericParameter(orig) : null);
			if (obj2 == null)
			{
				IGenericParameterProvider obj3 = ((provider is MemberReference) ? provider : null);
				if (obj3 == null)
				{
					return null;
				}
				TypeReference declaringType = ((MemberReference)obj3).DeclaringType;
				if (declaringType == null)
				{
					return null;
				}
				obj2 = ((IGenericParameterProvider)(object)declaringType).ResolveGenericParameter(orig);
			}
			return (GenericParameter)obj2;
		}

		public static IMetadataTokenProvider Relink(this IMetadataTokenProvider mtp, Relinker relinker, IGenericParameterProvider context)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			if (mtp is TypeReference)
			{
				return (IMetadataTokenProvider)(object)Extensions.Relink((TypeReference)mtp, relinker, context);
			}
			if (mtp is MethodReference)
			{
				return Extensions.Relink((MethodReference)mtp, relinker, context);
			}
			if (mtp is FieldReference)
			{
				return Extensions.Relink((FieldReference)mtp, relinker, context);
			}
			if (mtp is ParameterDefinition)
			{
				return (IMetadataTokenProvider)(object)Extensions.Relink((ParameterDefinition)mtp, relinker, context);
			}
			if (mtp is CallSite)
			{
				return (IMetadataTokenProvider)(object)Extensions.Relink((CallSite)mtp, relinker, context);
			}
			throw new InvalidOperationException($"MonoMod can't handle metadata token providers of the type {((object)mtp).GetType()}");
		}

		public static TypeReference Relink(this TypeReference type, Relinker relinker, IGenericParameterProvider context)
		{
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00f8: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			if (type == null)
			{
				return null;
			}
			TypeSpecification val = (TypeSpecification)(object)((type is TypeSpecification) ? type : null);
			if (val != null)
			{
				TypeReference val2 = val.ElementType.Relink(relinker, context);
				if (type.IsSentinel)
				{
					return (TypeReference)new SentinelType(val2);
				}
				if (type.IsByReference)
				{
					return (TypeReference)new ByReferenceType(val2);
				}
				if (type.IsPointer)
				{
					return (TypeReference)new PointerType(val2);
				}
				if (type.IsPinned)
				{
					return (TypeReference)new PinnedType(val2);
				}
				if (type.IsArray)
				{
					ArrayType val3 = new ArrayType(val2, ((ArrayType)type).Rank);
					for (int i = 0; i < val3.Rank; i++)
					{
						val3.Dimensions[i] = ((ArrayType)type).Dimensions[i];
					}
					return (TypeReference)(object)val3;
				}
				if (type.IsRequiredModifier)
				{
					return (TypeReference)new RequiredModifierType(((RequiredModifierType)type).ModifierType.Relink(relinker, context), val2);
				}
				if (type.IsOptionalModifier)
				{
					return (TypeReference)new OptionalModifierType(((OptionalModifierType)type).ModifierType.Relink(relinker, context), val2);
				}
				if (type.IsGenericInstance)
				{
					GenericInstanceType val4 = new GenericInstanceType(val2);
					Enumerator<TypeReference> enumerator = ((GenericInstanceType)type).GenericArguments.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							TypeReference current = enumerator.Current;
							val4.GenericArguments.Add(current?.Relink(relinker, context));
						}
						return (TypeReference)(object)val4;
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				if (type.IsFunctionPointer)
				{
					FunctionPointerType val5 = (FunctionPointerType)type;
					val5.ReturnType = val5.ReturnType.Relink(relinker, context);
					for (int j = 0; j < val5.Parameters.Count; j++)
					{
						((ParameterReference)val5.Parameters[j]).ParameterType = ((ParameterReference)val5.Parameters[j]).ParameterType.Relink(relinker, context);
					}
					return (TypeReference)(object)val5;
				}
				throw new NotSupportedException($"MonoMod can't handle TypeSpecification: {((MemberReference)type).FullName} ({((object)type).GetType()})");
			}
			if (!type.IsGenericParameter || context == null)
			{
				return (TypeReference)relinker((IMetadataTokenProvider)(object)type, context);
			}
			GenericParameter val6 = context.ResolveGenericParameter((GenericParameter)type);
			if (val6 == null)
			{
				throw new RelinkTargetNotFoundException(string.Format("{0} {1} (context: {2})", "MonoMod relinker failed finding", ((MemberReference)type).FullName, context), (IMetadataTokenProvider)(object)type, (IMetadataTokenProvider)(object)context);
			}
			for (int k = 0; k < val6.Constraints.Count; k++)
			{
				if (!val6.Constraints[k].GetConstraintType().IsGenericInstance)
				{
					val6.Constraints[k] = val6.Constraints[k].Relink(relinker, context);
				}
			}
			return (TypeReference)(object)val6;
		}

		public static IMetadataTokenProvider Relink(this MethodReference method, Relinker relinker, IGenericParameterProvider context)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			if (method.IsGenericInstance)
			{
				GenericInstanceMethod val = (GenericInstanceMethod)method;
				GenericInstanceMethod val2 = new GenericInstanceMethod((MethodReference)((MethodSpecification)val).ElementMethod.Relink(relinker, context));
				Enumerator<TypeReference> enumerator = val.GenericArguments.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						TypeReference current = enumerator.Current;
						val2.GenericArguments.Add(current.Relink(relinker, context));
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				return (IMetadataTokenProvider)(MethodReference)relinker((IMetadataTokenProvider)(object)val2, context);
			}
			MethodReference val3 = new MethodReference(((MemberReference)method).Name, method.ReturnType, ((MemberReference)method).DeclaringType.Relink(relinker, context));
			val3.CallingConvention = method.CallingConvention;
			val3.ExplicitThis = method.ExplicitThis;
			val3.HasThis = method.HasThis;
			Enumerator<GenericParameter> enumerator2 = method.GenericParameters.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					GenericParameter current2 = enumerator2.Current;
					val3.GenericParameters.Add(current2.Relink(relinker, context));
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			val3.ReturnType = val3.ReturnType?.Relink(relinker, (IGenericParameterProvider)(object)val3);
			Enumerator<ParameterDefinition> enumerator3 = method.Parameters.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					ParameterDefinition current3 = enumerator3.Current;
					((ParameterReference)current3).ParameterType = ((ParameterReference)current3).ParameterType.Relink(relinker, (IGenericParameterProvider)(object)method);
					val3.Parameters.Add(current3);
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			retur

BepInEx/plugins/LC_API.dll

Decompiled 8 months ago
using System;
using System.Collections.Concurrent;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LC_API.BundleAPI;
using LC_API.Comp;
using LC_API.Data;
using LC_API.Extensions;
using LC_API.GameInterfaceAPI;
using LC_API.ManualPatches;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("LC_API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Utilities for plugin devs")]
[assembly: AssemblyFileVersion("2.1.1.0")]
[assembly: AssemblyInformationalVersion("2.1.1")]
[assembly: AssemblyProduct("LC_API")]
[assembly: AssemblyTitle("LC_API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LC_API
{
	internal static class CheatDatabase
	{
		private const string DAT_CD_BROADCAST = "LC_API_CD_Broadcast";

		private const string SIG_REQ_GUID = "LC_API_ReqGUID";

		private const string SIG_SEND_MODS = "LC_APISendMods";

		private static Dictionary<string, PluginInfo> PluginsLoaded = new Dictionary<string, PluginInfo>();

		public static void RunLocalCheatDetector()
		{
			PluginsLoaded = Chainloader.PluginInfos;
			using Dictionary<string, PluginInfo>.ValueCollection.Enumerator enumerator = PluginsLoaded.Values.GetEnumerator();
			while (enumerator.MoveNext())
			{
				switch (enumerator.Current.Metadata.GUID)
				{
				case "mikes.lethalcompany.mikestweaks":
				case "mom.llama.enhancer":
				case "Posiedon.GameMaster":
				case "LethalCompanyScalingMaster":
				case "verity.amberalert":
					ModdedServer.SetServerModdedOnly();
					break;
				}
			}
		}

		public static void OtherPlayerCheatDetector()
		{
			Plugin.Log.LogWarning((object)"Asking all other players for their mod list..");
			GameTips.ShowTip("Mod List:", "Asking all other players for installed mods..");
			GameTips.ShowTip("Mod List:", "Check the logs for more detailed results.\n<size=13>(Note that if someone doesnt show up on the list, they may not have LC_API installed)</size>");
			Networking.Broadcast("LC_API_CD_Broadcast", "LC_API_ReqGUID");
		}

		internal static void CDNetGetString(string data, string signature)
		{
			if (data == "LC_API_CD_Broadcast" && signature == "LC_API_ReqGUID")
			{
				string text = "";
				foreach (PluginInfo value in PluginsLoaded.Values)
				{
					text = text + "\n" + value.Metadata.GUID;
				}
				Networking.Broadcast(GameNetworkManager.Instance.localPlayerController.playerUsername + " responded with these mods:" + text, "LC_APISendMods");
			}
			if (signature == "LC_APISendMods")
			{
				GameTips.ShowTip("Mod List:", data);
				Plugin.Log.LogWarning((object)data);
			}
		}
	}
	[BepInPlugin("LC_API", "LC_API", "2.1.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private ConfigEntry<bool> configOverrideModServer;

		private ConfigEntry<bool> configLegacyAssetLoading;

		private ConfigEntry<bool> configDisableBundleLoader;

		public static bool Initialized { get; private set; }

		private void Awake()
		{
			//IL_00a5: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			configOverrideModServer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force modded server browser", false, "Should the API force you into the modded server browser?");
			configLegacyAssetLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Legacy asset bundle loading", false, "Should the BundleLoader use legacy asset loading? Turning this on may help with loading assets from older plugins.");
			configDisableBundleLoader = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Disable BundleLoader", false, "Should the BundleLoader be turned off? Enable this if you are having problems with mods that load assets using a different method from LC_API's BundleLoader.");
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogWarning((object)"\n.____    _________           _____  __________ .___  \r\n|    |   \\_   ___ \\         /  _  \\ \\______   \\|   | \r\n|    |   /    \\  \\/        /  /_\\  \\ |     ___/|   | \r\n|    |___\\     \\____      /    |    \\|    |    |   | \r\n|_______ \\\\______  /______\\____|__  /|____|    |___| \r\n        \\/       \\//_____/        \\/                 \r\n                                                     ");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Starting up..");
			if (configOverrideModServer.Value)
			{
				ModdedServer.SetServerModdedOnly();
			}
			Harmony val = new Harmony("ModAPI");
			MethodInfo methodInfo = AccessTools.Method(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated", (Type[])null, (Type[])null);
			AccessTools.Method(typeof(GameNetworkManager), "LobbyDataIsJoinable", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ServerPatch), "OnLobbyCreate", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(MenuManager), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(ServerPatch), "CacheMenuManager", (Type[])null, (Type[])null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(ServerPatch), "ChatInterpreter", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, new Action<string, string>(CheatDatabase.CDNetGetString));
			Networking.GetListString = (Action<List<string>, string>)Delegate.Combine(Networking.GetListString, new Action<List<string>, string>(Networking.LCAPI_NET_SYNCVAR_SET));
		}

		internal void Start()
		{
			Initialize();
		}

		internal void OnDestroy()
		{
			Initialize();
		}

		internal void Initialize()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!Initialized)
			{
				Initialized = true;
				if (!configDisableBundleLoader.Value)
				{
					BundleLoader.Load(configLegacyAssetLoading.Value);
				}
				GameObject val = new GameObject("API");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<LC_APIManager>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Started!");
				CheatDatabase.RunLocalCheatDetector();
			}
		}

		internal static void PatchMethodManual(MethodInfo method, MethodInfo patch, Harmony harmony)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			harmony.Patch((MethodBase)method, new HarmonyMethod(patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LC_API";

		public const string PLUGIN_NAME = "LC_API";

		public const string PLUGIN_VERSION = "2.1.1";
	}
}
namespace LC_API.ServerAPI
{
	public static class ModdedServer
	{
		private static bool moddedOnly;

		[Obsolete("Use SetServerModdedOnly() instead. This will be removed/private in a future update.")]
		public static bool setModdedOnly;

		public static bool ModdedOnly => moddedOnly;

		public static void SetServerModdedOnly()
		{
			moddedOnly = true;
			Plugin.Log.LogMessage((object)"A plugin has set your game to only allow you to play with other people who have mods!");
		}

		public static void OnSceneLoaded()
		{
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && ModdedOnly)
			{
				GameNetworkManager instance = GameNetworkManager.Instance;
				instance.gameVersionNum += 16440;
				setModdedOnly = true;
			}
		}
	}
	public static class Networking
	{
		public static Action<string, string> GetString = delegate
		{
		};

		public static Action<List<string>, string> GetListString = delegate
		{
		};

		public static Action<int, string> GetInt = delegate
		{
		};

		public static Action<float, string> GetFloat = delegate
		{
		};

		public static Action<Vector3, string> GetVector3 = delegate
		{
		};

		private static Dictionary<string, string> syncStringVars = new Dictionary<string, string>();

		public static void Broadcast(string data, string signature)
		{
			if (data.Contains("/"))
			{
				Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
				return;
			}
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDstring.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(List<string> data, string signature)
		{
			string text = "";
			foreach (string datum in data)
			{
				if (datum.Contains("/"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
					return;
				}
				if (datum.Contains("\n"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( NewLine )");
					return;
				}
				text = text + datum + "\n";
			}
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data?.ToString() + "/" + signature + "/" + NetworkBroadcastDataType.BDlistString.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(int data, string signature)
		{
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDint.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(float data, string signature)
		{
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDfloat.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(Vector3 data, string signature)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			HUDManager instance = HUDManager.Instance;
			string[] obj = new string[9] { "<size=0>NWE/", null, null, null, null, null, null, null, null };
			Vector3 val = data;
			obj[1] = ((object)(Vector3)(ref val)).ToString();
			obj[2] = "/";
			obj[3] = signature;
			obj[4] = "/";
			obj[5] = NetworkBroadcastDataType.BDvector3.ToString();
			obj[6] = "/";
			obj[7] = GameNetworkManager.Instance.localPlayerController.playerClientId.ToString();
			obj[8] = "/</size>";
			instance.AddTextToChatOnServer(string.Concat(obj), -1);
		}

		public static void RegisterSyncVariable(string name)
		{
			if (!syncStringVars.ContainsKey(name))
			{
				syncStringVars.Add(name, "");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot register Sync Variable! A Sync Variable has already been registered with name " + name));
			}
		}

		public static void SetSyncVariable(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
				Broadcast(new List<string> { name, value }, "LCAPI_NET_SYNCVAR_SET");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		private static void SetSyncVariableB(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		internal static void LCAPI_NET_SYNCVAR_SET(List<string> list, string arg2)
		{
			if (arg2 == "LCAPI_NET_SYNCVAR_SET")
			{
				SetSyncVariableB(list[0], list[1]);
			}
		}

		public static string GetSyncVariable(string name)
		{
			if (syncStringVars.ContainsKey(name))
			{
				return syncStringVars[name];
			}
			Plugin.Log.LogError((object)("Cannot get the value of Sync Variable " + name + " as it is not registered!"));
			return "";
		}

		private static void GotString(string data, string signature)
		{
		}

		private static void GotInt(int data, string signature)
		{
		}

		private static void GotFloat(float data, string signature)
		{
		}

		private static void GotVector3(Vector3 data, string signature)
		{
		}
	}
}
namespace LC_API.ManualPatches
{
	internal static class ServerPatch
	{
		internal static bool OnLobbyCreate(GameNetworkManager __instance, Result result, Lobby lobby)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)result != 1)
			{
				Debug.LogError((object)$"Lobby could not be created! {result}", (Object)(object)__instance);
			}
			__instance.lobbyHostSettings.lobbyName = "[MODDED]" + __instance.lobbyHostSettings.lobbyName.ToString();
			Plugin.Log.LogMessage((object)"server pre-setup success");
			return true;
		}

		internal static bool CacheMenuManager(MenuManager __instance)
		{
			LC_APIManager.MenuManager = __instance;
			return true;
		}

		internal static bool ChatInterpreter(HUDManager __instance, string chatMessage)
		{
			//IL_0312: 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_03a2: 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)
			if (!chatMessage.Contains("NWE") || !chatMessage.Contains("<size=0>"))
			{
				return true;
			}
			string[] array = chatMessage.Split(new char[1] { '/' });
			if (array.Length < 5)
			{
				if (array.Length >= 3)
				{
					if (!int.TryParse(array[4], out var result))
					{
						Plugin.Log.LogWarning((object)"Failed to parse player ID!!");
						return false;
					}
					if ((result == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
					{
						return false;
					}
					Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result2);
					switch (result2)
					{
					case NetworkBroadcastDataType.BDstring:
						Networking.GetString(array[1], array[2]);
						break;
					case NetworkBroadcastDataType.BDint:
						Networking.GetInt(int.Parse(array[1]), array[2]);
						break;
					case NetworkBroadcastDataType.BDfloat:
						Networking.GetFloat(float.Parse(array[1]), array[2]);
						break;
					case NetworkBroadcastDataType.BDvector3:
					{
						string[] array2 = array[1].Replace("(", "").Replace(")", "").Split(new char[1] { ',' });
						Vector3 arg = default(Vector3);
						if (array2.Length == 3)
						{
							if (float.TryParse(array2[0], out var result3) && float.TryParse(array2[1], out var result4) && float.TryParse(array2[2], out var result5))
							{
								arg.x = result3;
								arg.y = result4;
								arg.z = result5;
							}
							else
							{
								Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
							}
						}
						else
						{
							Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
						}
						Networking.GetVector3(arg, array[2]);
						break;
					}
					case NetworkBroadcastDataType.BDlistString:
					{
						string[] source = array[1].Split(new char[1] { '\n' });
						Networking.GetListString(source.ToList(), array[2]);
						break;
					}
					}
					_ = LC_APIManager.netTester;
					return false;
				}
				Plugin.Log.LogError((object)"Generic Network receive fail. This is a failure of the API, and it should be reported as a bug.");
				Plugin.Log.LogError((object)$"Generic Network receive fail (expected 5+ data fragments, got {array.Length}). This is a failure of the API, and it should be reported as a bug.");
				return true;
			}
			if (!int.TryParse(array[4], out var result6))
			{
				Plugin.Log.LogWarning((object)("Failed to parse player ID '" + array[4] + "'!!"));
				return false;
			}
			if ((result6 == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
			{
				return false;
			}
			if (!Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result7))
			{
				Plugin.Log.LogError((object)("Unknown datatype - unable to parse '" + array[3] + "' into a known data type!"));
				return false;
			}
			switch (result7)
			{
			case NetworkBroadcastDataType.BDstring:
				Networking.GetString.InvokeActionSafe(array[1], array[2]);
				break;
			case NetworkBroadcastDataType.BDint:
				Networking.GetInt.InvokeActionSafe(int.Parse(array[1]), array[2]);
				break;
			case NetworkBroadcastDataType.BDfloat:
				Networking.GetFloat.InvokeActionSafe(float.Parse(array[1]), array[2]);
				break;
			case NetworkBroadcastDataType.BDvector3:
			{
				string text = array[1].Trim('(', ')');
				string[] array3 = text.Split(new char[1] { ',' });
				Vector3 param = default(Vector3);
				float result8;
				float result9;
				float result10;
				if (array3.Length != 3)
				{
					Plugin.Log.LogError((object)$"Vector3 Network receive fail (expected 3 numbers, got {array3.Length} number(?)(s) instead). This is a failure of the API, and it should be reported as a bug. (passing an empty Vector3 in its place)");
				}
				else if (float.TryParse(array3[0], out result8) && float.TryParse(array3[1], out result9) && float.TryParse(array3[2], out result10))
				{
					param.x = result8;
					param.y = result9;
					param.z = result10;
				}
				else
				{
					Plugin.Log.LogError((object)("Vector3 Network receive fail (failed to parse '" + text + "' as numbers). This is a failure of the API, and it should be reported as a bug."));
				}
				Networking.GetVector3.InvokeActionSafe(param, array[2]);
				break;
			}
			}
			_ = LC_APIManager.netTester;
			return false;
		}

		internal static bool ChatCommands(HUDManager __instance, CallbackContext context)
		{
			if (__instance.chatTextField.text.ToLower().Contains("/modcheck"))
			{
				CheatDatabase.OtherPlayerCheatDetector();
				return false;
			}
			return true;
		}
	}
}
namespace LC_API.GameInterfaceAPI
{
	public static class GameState
	{
		private static readonly Action NothingAction = delegate
		{
		};

		public static int AlivePlayerCount { get; private set; }

		public static ShipState ShipState { get; private set; }

		public static event Action PlayerDied;

		public static event Action LandOnMoon;

		public static event Action WentIntoOrbit;

		public static event Action ShipStartedLeaving;

		internal static void GSUpdate()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (StartOfRound.Instance.shipHasLanded && ShipState != ShipState.OnMoon)
				{
					ShipState = ShipState.OnMoon;
					GameState.LandOnMoon.InvokeActionSafe();
				}
				if (StartOfRound.Instance.inShipPhase && ShipState != 0)
				{
					ShipState = ShipState.InOrbit;
					GameState.WentIntoOrbit.InvokeActionSafe();
				}
				if (StartOfRound.Instance.shipIsLeaving && ShipState != ShipState.LeavingMoon)
				{
					ShipState = ShipState.LeavingMoon;
					GameState.ShipStartedLeaving.InvokeActionSafe();
				}
				if (AlivePlayerCount < StartOfRound.Instance.livingPlayers)
				{
					GameState.PlayerDied.InvokeActionSafe();
				}
				AlivePlayerCount = StartOfRound.Instance.livingPlayers;
			}
		}

		static GameState()
		{
			GameState.PlayerDied = NothingAction;
			GameState.LandOnMoon = NothingAction;
			GameState.WentIntoOrbit = NothingAction;
			GameState.ShipStartedLeaving = NothingAction;
		}
	}
	public class GameTips
	{
		private static List<string> tipHeaders = new List<string>();

		private static List<string> tipBodys = new List<string>();

		private static float lastMessageTime;

		public static void ShowTip(string header, string body)
		{
			tipHeaders.Add(header);
			tipBodys.Add(body);
		}

		public static void UpdateInternal()
		{
			lastMessageTime -= Time.deltaTime;
			if ((tipHeaders.Count > 0) & (lastMessageTime < 0f))
			{
				lastMessageTime = 5f;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.DisplayTip(tipHeaders[0], tipBodys[0], false, false, "LC_Tip1");
				}
				tipHeaders.RemoveAt(0);
				tipBodys.RemoveAt(0);
			}
		}
	}
}
namespace LC_API.Extensions
{
	public static class DelegateExtensions
	{
		private static readonly PropertyInfo PluginGetLogger = AccessTools.Property(typeof(BaseUnityPlugin), "Logger");

		public static void InvokeActionSafe(this Action action)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action)@delegate)();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		public static void InvokeActionSafe<T>(this Action<T> action, T param)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action<T>)@delegate)(param);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		public static void InvokeActionSafe<T1, T2>(this Action<T1, T2> action, T1 param1, T2 param2)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action<T1, T2>)@delegate)(param1, param2);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		internal static void InvokeParameterlessDelegate<T>(this T paramlessDelegate) where T : Delegate
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if ((Delegate?)paramlessDelegate == (Delegate?)null)
			{
				return;
			}
			Delegate[] invocationList = paramlessDelegate.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((T)@delegate).DynamicInvoke();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}
	}
}
namespace LC_API.Data
{
	internal enum NetworkBroadcastDataType
	{
		Unknown,
		BDint,
		BDfloat,
		BDvector3,
		BDstring,
		BDlistString
	}
	public enum ShipState
	{
		InOrbit,
		OnMoon,
		LeavingMoon
	}
}
namespace LC_API.Comp
{
	internal class LC_APIManager : MonoBehaviour
	{
		public static MenuManager MenuManager;

		public static bool netTester;

		private static int playerCount;

		private static bool wanttoCheckMods;

		private static float lobbychecktimer;

		public void Update()
		{
			GameState.GSUpdate();
			GameTips.UpdateInternal();
			if ((((Object)(object)HUDManager.Instance != (Object)null) & netTester) && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
			{
				Networking.Broadcast("testerData", "testerSignature");
			}
			if (!ModdedServer.setModdedOnly)
			{
				ModdedServer.OnSceneLoaded();
			}
			else if (ModdedServer.ModdedOnly && (Object)(object)MenuManager != (Object)null && Object.op_Implicit((Object)(object)MenuManager.versionNumberText))
			{
				((TMP_Text)MenuManager.versionNumberText).text = $"v{GameNetworkManager.Instance.gameVersionNum - 16440}\nMOD";
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				if (playerCount < GameNetworkManager.Instance.connectedPlayers)
				{
					lobbychecktimer = -4.5f;
					wanttoCheckMods = true;
				}
				playerCount = GameNetworkManager.Instance.connectedPlayers;
			}
			if (lobbychecktimer < 0f)
			{
				lobbychecktimer += Time.deltaTime;
			}
			else if (wanttoCheckMods)
			{
				wanttoCheckMods = false;
				CD();
			}
		}

		private void CD()
		{
			CheatDatabase.OtherPlayerCheatDetector();
		}
	}
}
namespace LC_API.BundleAPI
{
	public static class BundleLoader
	{
		[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
		public delegate void OnLoadedAssetsDelegate();

		[Obsolete("Use GetLoadedAsset instead. This will be removed/private in a future update.")]
		public static ConcurrentDictionary<string, Object> assets = new ConcurrentDictionary<string, Object>();

		[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
		public static OnLoadedAssetsDelegate OnLoadedAssets = LoadAssetsCompleted;

		public static bool AssetsInLegacyDirectory { get; private set; }

		public static bool LegacyLoadingEnabled { get; private set; }

		public static event Action OnLoadedBundles;

		internal static void Load(bool legacyLoading)
		{
			LegacyLoadingEnabled = legacyLoading;
			Plugin.Log.LogMessage((object)"BundleAPI will now load all asset bundles...");
			string path = Path.Combine(Paths.BepInExRootPath, "Bundles");
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
				Plugin.Log.LogMessage((object)"BundleAPI Created legacy bundle directory in BepInEx/Bundles");
			}
			string[] array = (from x in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
				where !x.EndsWith(".manifest", StringComparison.CurrentCultureIgnoreCase)
				select x).ToArray();
			AssetsInLegacyDirectory = array.Length != 0;
			if (!AssetsInLegacyDirectory)
			{
				Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from legacy directory");
			}
			if (AssetsInLegacyDirectory)
			{
				Plugin.Log.LogWarning((object)"The path BepInEx > Bundles is outdated and should not be used anymore! Bundles will be loaded from BepInEx > plugins from now on");
				LoadAllAssetsFromDirectory(array, legacyLoading);
			}
			path = Path.Combine(Paths.BepInExRootPath, "plugins");
			array = (from x in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
				where !x.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".json", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".png", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".md", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".old", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase)
				select x).ToArray();
			if (array.Length == 0)
			{
				Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from plugins folder");
			}
			else
			{
				LoadAllAssetsFromDirectory(array, legacyLoading);
			}
			OnLoadedAssets.InvokeParameterlessDelegate();
			BundleLoader.OnLoadedBundles.InvokeActionSafe();
		}

		private static void LoadAllAssetsFromDirectory(string[] array, bool legacyLoading)
		{
			if (legacyLoading)
			{
				Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
				for (int i = 0; i < array.Length; i++)
				{
					try
					{
						SaveAsset(array[i], legacyLoading);
					}
					catch (Exception)
					{
						Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[i]));
					}
				}
				return;
			}
			Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
			for (int j = 0; j < array.Length; j++)
			{
				try
				{
					SaveAsset(array[j], legacyLoading);
				}
				catch (Exception)
				{
					Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[j]));
				}
			}
		}

		public static void SaveAsset(string path, bool legacyLoad)
		{
			AssetBundle val = AssetBundle.LoadFromFile(path);
			try
			{
				string[] allAssetNames = val.GetAllAssetNames();
				foreach (string text in allAssetNames)
				{
					Plugin.Log.LogMessage((object)("Got asset for load: " + text));
					Object val2 = val.LoadAsset(text);
					if (val2 == (Object)null)
					{
						Plugin.Log.LogWarning((object)$"Skipped/failed loading an asset (from bundle '{((Object)val).name}') - Asset path: {val2}");
						continue;
					}
					string key = (legacyLoad ? text.ToUpper() : text.ToLower());
					if (assets.ContainsKey(key))
					{
						Plugin.Log.LogError((object)"BundleAPI got duplicate asset!");
						break;
					}
					assets.TryAdd(key, val2);
					Plugin.Log.LogMessage((object)("Loaded asset: " + val2.name));
				}
			}
			finally
			{
				if (val != null)
				{
					val.Unload(false);
				}
			}
		}

		public static TAsset GetLoadedAsset<TAsset>(string itemPath) where TAsset : Object
		{
			Object value = null;
			if (LegacyLoadingEnabled)
			{
				assets.TryGetValue(itemPath.ToUpper(), out value);
			}
			if (value == (Object)null)
			{
				assets.TryGetValue(itemPath.ToLower(), out value);
			}
			return (TAsset)(object)value;
		}

		private static void LoadAssetsCompleted()
		{
			Plugin.Log.LogMessage((object)"BundleAPI finished loading all assets.");
		}

		static BundleLoader()
		{
			BundleLoader.OnLoadedBundles = LoadAssetsCompleted;
		}
	}
}

BepInEx/plugins/MoreSuits.dll

Decompiled 8 months ago
using System;
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 BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MoreSuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds more suit options to Lethal Company")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1")]
[assembly: AssemblyProduct("MoreSuits")]
[assembly: AssemblyTitle("MoreSuits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.1.0")]
[module: UnverifiableCode]
namespace MoreSuits;

[BepInPlugin("x753.More_Suits", "More Suits", "1.4.1")]
public class MoreSuitsMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(ref StartOfRound __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			try
			{
				if (SuitsAdded)
				{
					return;
				}
				int count = __instance.unlockablesList.unlockables.Count;
				UnlockableItem val = new UnlockableItem();
				int num = 0;
				for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val2 = __instance.unlockablesList.unlockables[i];
					if (!((Object)(object)val2.suitMaterial != (Object)null) || !val2.alreadyUnlocked)
					{
						continue;
					}
					val = val2;
					List<string> list = Directory.GetDirectories(Paths.PluginPath, "moresuits", SearchOption.AllDirectories).ToList();
					List<string> list2 = new List<string>();
					List<string> list3 = new List<string>();
					List<string> list4 = DisabledSuits.ToLower().Replace(".png", "").Split(',')
						.ToList();
					List<string> list5 = new List<string>();
					if (!LoadAllSuits)
					{
						foreach (string item2 in list)
						{
							if (File.Exists(Path.Combine(item2, "!less-suits.txt")))
							{
								string[] collection = new string[9] { "glow", "kirby", "knuckles", "luigi", "mario", "minion", "skeleton", "slayer", "smile" };
								list5.AddRange(collection);
								break;
							}
						}
					}
					foreach (string item3 in list)
					{
						if (item3 != "")
						{
							string[] files = Directory.GetFiles(item3, "*.png");
							string[] files2 = Directory.GetFiles(item3, "*.matbundle");
							list2.AddRange(files);
							list3.AddRange(files2);
						}
					}
					list3.Sort();
					list2.Sort();
					try
					{
						foreach (string item4 in list3)
						{
							Object[] array = AssetBundle.LoadFromFile(item4).LoadAllAssets();
							foreach (Object val3 in array)
							{
								if (val3 is Material)
								{
									Material item = (Material)val3;
									customMaterials.Add(item);
								}
							}
						}
					}
					catch (Exception ex)
					{
						Debug.Log((object)("Something went wrong with More Suits! Could not load materials from asset bundle(s). Error: " + ex));
					}
					foreach (string item5 in list2)
					{
						if (list4.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()))
						{
							continue;
						}
						string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
						if (list5.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()) && item5.Contains(directoryName))
						{
							continue;
						}
						UnlockableItem val4;
						Material val5;
						if (Path.GetFileNameWithoutExtension(item5).ToLower() == "default")
						{
							val4 = val;
							val5 = val4.suitMaterial;
						}
						else
						{
							val4 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
							val5 = Object.Instantiate<Material>(val4.suitMaterial);
						}
						byte[] array2 = File.ReadAllBytes(item5);
						Texture2D val6 = new Texture2D(2, 2);
						ImageConversion.LoadImage(val6, array2);
						val5.mainTexture = (Texture)(object)val6;
						val4.unlockableName = Path.GetFileNameWithoutExtension(item5);
						try
						{
							string path = Path.Combine(Path.GetDirectoryName(item5), "advanced", val4.unlockableName + ".json");
							if (File.Exists(path))
							{
								string[] array3 = File.ReadAllLines(path);
								for (int j = 0; j < array3.Length; j++)
								{
									string[] array4 = array3[j].Trim().Split(':');
									if (array4.Length != 2)
									{
										continue;
									}
									string text = array4[0].Trim('"', ' ', ',');
									string text2 = array4[1].Trim('"', ' ', ',');
									if (text2.Contains(".png"))
									{
										byte[] array5 = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(item5), "advanced", text2));
										Texture2D val7 = new Texture2D(2, 2);
										ImageConversion.LoadImage(val7, array5);
										val5.SetTexture(text, (Texture)(object)val7);
										continue;
									}
									if (text == "PRICE" && int.TryParse(text2, out var result))
									{
										try
										{
											val4 = AddToRotatingShop(val4, result, __instance.unlockablesList.unlockables.Count);
										}
										catch (Exception ex2)
										{
											Debug.Log((object)("Something went wrong with More Suits! Could not add a suit to the rotating shop. Error: " + ex2));
										}
										continue;
									}
									switch (text2)
									{
									case "KEYWORD":
										val5.EnableKeyword(text);
										continue;
									case "DISABLEKEYWORD":
										val5.DisableKeyword(text);
										continue;
									case "SHADERPASS":
										val5.SetShaderPassEnabled(text, true);
										continue;
									case "DISABLESHADERPASS":
										val5.SetShaderPassEnabled(text, false);
										continue;
									}
									float result2;
									Vector4 vector;
									if (text == "SHADER")
									{
										Shader shader = Shader.Find(text2);
										val5.shader = shader;
									}
									else if (text == "MATERIAL")
									{
										foreach (Material customMaterial in customMaterials)
										{
											if (((Object)customMaterial).name == text2)
											{
												val5 = Object.Instantiate<Material>(customMaterial);
												val5.mainTexture = (Texture)(object)val6;
												break;
											}
										}
									}
									else if (float.TryParse(text2, out result2))
									{
										val5.SetFloat(text, result2);
									}
									else if (TryParseVector4(text2, out vector))
									{
										val5.SetVector(text, vector);
									}
								}
							}
						}
						catch (Exception ex3)
						{
							Debug.Log((object)("Something went wrong with More Suits! Error: " + ex3));
						}
						val4.suitMaterial = val5;
						if (val4.unlockableName.ToLower() != "default")
						{
							if (num == MaxSuits)
							{
								Debug.Log((object)"Attempted to add a suit, but you've already reached the max number of suits! Modify the config if you want more.");
								continue;
							}
							__instance.unlockablesList.unlockables.Add(val4);
							num++;
						}
					}
					SuitsAdded = true;
					break;
				}
				UnlockableItem val8 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
				val8.alreadyUnlocked = false;
				val8.hasBeenMoved = false;
				val8.placedPosition = Vector3.zero;
				val8.placedRotation = Vector3.zero;
				val8.unlockableType = 753;
				while (__instance.unlockablesList.unlockables.Count < count + MaxSuits)
				{
					__instance.unlockablesList.unlockables.Add(val8);
				}
			}
			catch (Exception ex4)
			{
				Debug.Log((object)("Something went wrong with More Suits! Error: " + ex4));
			}
		}

		[HarmonyPatch("PositionSuitsOnRack")]
		[HarmonyPrefix]
		private static bool PositionSuitsOnRackPatch(ref StartOfRound __instance)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00bd: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<UnlockableSuit> source = Object.FindObjectsOfType<UnlockableSuit>().ToList();
			source = source.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value).ToList();
			int num = 0;
			foreach (UnlockableSuit item in source)
			{
				AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>();
				component.overrideOffset = true;
				float num2 = 0.18f;
				if (MakeSuitsFitOnRack && source.Count > 13)
				{
					num2 /= (float)Math.Min(source.Count, 20) / 12f;
				}
				component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + __instance.rightmostSuitPosition.forward * num2 * (float)num;
				component.rotationOffset = new Vector3(0f, 90f, 0f);
				num++;
			}
			return false;
		}
	}

	private const string modGUID = "x753.More_Suits";

	private const string modName = "More Suits";

	private const string modVersion = "1.4.1";

	private readonly Harmony harmony = new Harmony("x753.More_Suits");

	private static MoreSuitsMod Instance;

	public static bool SuitsAdded = false;

	public static string DisabledSuits;

	public static bool LoadAllSuits;

	public static bool MakeSuitsFitOnRack;

	public static int MaxSuits;

	public static List<Material> customMaterials = new List<Material>();

	private static TerminalNode cancelPurchase;

	private static TerminalKeyword buyKeyword;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		DisabledSuits = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Disabled Suit List", "UglySuit751.png,UglySuit752.png,UglySuit753.png", "Comma-separated list of suits that shouldn't be loaded").Value;
		LoadAllSuits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Ignore !less-suits.txt", false, "If true, ignores the !less-suits.txt file and will attempt to load every suit, except those in the disabled list. This should be true if you're not worried about having too many suits.").Value;
		MakeSuitsFitOnRack = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Make Suits Fit on Rack", true, "If true, squishes the suits together so more can fit on the rack.").Value;
		MaxSuits = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Suits", 100, "The maximum number of suits to load. If you have more, some will be ignored.").Value;
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin More Suits is loaded!");
	}

	private static UnlockableItem AddToRotatingShop(UnlockableItem newSuit, int price, int unlockableID)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		Terminal val = Object.FindObjectOfType<Terminal>();
		for (int i = 0; i < val.terminalNodes.allKeywords.Length; i++)
		{
			if (((Object)val.terminalNodes.allKeywords[i]).name == "Buy")
			{
				buyKeyword = val.terminalNodes.allKeywords[i];
				break;
			}
		}
		newSuit.alreadyUnlocked = false;
		newSuit.hasBeenMoved = false;
		newSuit.placedPosition = Vector3.zero;
		newSuit.placedRotation = Vector3.zero;
		newSuit.shopSelectionNode = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)newSuit.shopSelectionNode).name = newSuit.unlockableName + "SuitBuy1";
		newSuit.shopSelectionNode.creatureName = newSuit.unlockableName + " suit";
		newSuit.shopSelectionNode.displayText = "You have requested to order " + newSuit.unlockableName + " suits.\nTotal cost of item: [totalCost].\n\nPlease CONFIRM or DENY.\n\n";
		newSuit.shopSelectionNode.clearPreviousText = true;
		newSuit.shopSelectionNode.shipUnlockableID = unlockableID;
		newSuit.shopSelectionNode.itemCost = price;
		newSuit.shopSelectionNode.overrideOptions = true;
		CompatibleNoun val2 = new CompatibleNoun();
		val2.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val2.noun.word = "confirm";
		val2.noun.isVerb = true;
		val2.result = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)val2.result).name = newSuit.unlockableName + "SuitBuyConfirm";
		val2.result.creatureName = "";
		val2.result.displayText = "Ordered " + newSuit.unlockableName + " suits! Your new balance is [playerCredits].\n\n";
		val2.result.clearPreviousText = true;
		val2.result.shipUnlockableID = unlockableID;
		val2.result.buyUnlockable = true;
		val2.result.itemCost = price;
		val2.result.terminalEvent = "";
		CompatibleNoun val3 = new CompatibleNoun();
		val3.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val3.noun.word = "deny";
		val3.noun.isVerb = true;
		if ((Object)(object)cancelPurchase == (Object)null)
		{
			cancelPurchase = ScriptableObject.CreateInstance<TerminalNode>();
		}
		val3.result = cancelPurchase;
		((Object)val3.result).name = "MoreSuitsCancelPurchase";
		val3.result.displayText = "Cancelled order.\n";
		newSuit.shopSelectionNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { val2, val3 };
		TerminalKeyword val4 = ScriptableObject.CreateInstance<TerminalKeyword>();
		((Object)val4).name = newSuit.unlockableName + "Suit";
		val4.word = newSuit.unlockableName.ToLower() + " suit";
		val4.defaultVerb = buyKeyword;
		CompatibleNoun val5 = new CompatibleNoun();
		val5.noun = val4;
		val5.result = newSuit.shopSelectionNode;
		List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList();
		list.Add(val5);
		buyKeyword.compatibleNouns = list.ToArray();
		List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
		list2.Add(val4);
		list2.Add(val2.noun);
		list2.Add(val3.noun);
		val.terminalNodes.allKeywords = list2.ToArray();
		return newSuit;
	}

	public static bool TryParseVector4(string input, out Vector4 vector)
	{
		//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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		vector = Vector4.zero;
		string[] array = input.Split(',');
		if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4))
		{
			vector = new Vector4(result, result2, result3, result4);
			return true;
		}
		return false;
	}
}

BepInEx/plugins/SmallSuitRack/SmallSuitRack.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using SmallSuitRack.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("SmallSuitRack")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SmallSuitRack")]
[assembly: AssemblyTitle("SmallSuitRack")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SmallSuitRack
{
	[BepInPlugin("Mills.SmallSuitRack", "Small Suits and Rack", "1.0.0.0")]
	public class ModBase : BaseUnityPlugin
	{
		private const string modGUID = "Mills.SmallSuitRack";

		private const string modName = "Small Suits and Rack";

		private const string modVersion = "1.0.0.0";

		private readonly Harmony harmony = new Harmony("Mills.SmallSuitRack");

		internal ManualLogSource nls;

		private static ModBase instance;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			nls = Logger.CreateLogSource("Mills.SmallSuitRack");
			harmony.PatchAll(typeof(ModBase));
			harmony.PatchAll(typeof(SmallSuitRackPatch));
		}
	}
}
namespace SmallSuitRack.Patches
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class SmallSuitRackPatch
	{
		public static int calls;

		[HarmonyPatch("PositionSuitsOnRack")]
		[HarmonyPostfix]
		private static void PositionSuitsOnRackPatch(ref StartOfRound __instance)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_0127: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			List<UnlockableSuit> source = Object.FindObjectsOfType<UnlockableSuit>().ToList();
			source = source.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value).ToList();
			int num = 0;
			float num2 = 0.5f;
			float num3 = 0.18f;
			num3 *= num2 / 1.75f;
			foreach (UnlockableSuit item in source)
			{
				AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>();
				component.overrideOffset = true;
				component.positionOffset = new Vector3(-4f, 4f, -8.41f) + __instance.rightmostSuitPosition.forward * num3 * (float)num;
				component.rotationOffset = new Vector3(0f, 90f, 0f);
				num++;
			}
			if (calls < source.Count)
			{
				UnlockableSuit val = source[calls];
				if ((Object)(object)val != (Object)null)
				{
					Vector3 localScale = ((Component)val).transform.localScale;
					localScale.x *= num2;
					localScale.y *= num2;
					localScale.z *= num2 / 1.75f;
					((Component)val).transform.localScale = localScale;
				}
			}
			calls++;
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void LightHeightPatch(ref StartOfRound __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ShipLights shipRoomLights = __instance.shipRoomLights;
			Vector3 position = ((Component)shipRoomLights).transform.position;
			position.y += 0.5f;
			((Component)shipRoomLights).transform.position = position;
		}
	}
}

BepInEx/plugins/TooManySuits.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreSuits;
using TMPro;
using TooManySuits.Helper;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[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("TooManySuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TooManySuits")]
[assembly: AssemblyTitle("TooManySuits")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace TooManySuits
{
	[BepInPlugin("verity.TooManySuits", "Too Many Suits", "1.0.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource LogSource;

		public static ConfigEntry<string> NextButton;

		public static ConfigEntry<string> BackButton;

		public static ConfigEntry<float> TextScale;

		private void Awake()
		{
			//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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			LogSource = ((BaseUnityPlugin)this).Logger;
			NextButton = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Next-Page-Keybind", "<Keyboard>/n", "Next page button.");
			BackButton = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Back-Page-Keybind", "<Keyboard>/b", "Back page button.");
			TextScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Text-Scale", 0.003f, "Size of the text above the suit rack.");
			GameObject val = new GameObject("TooManySuits");
			val.AddComponent<PluginLoader>();
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)val);
		}
	}
	public class PluginLoader : MonoBehaviour
	{
		private class Hooks
		{
			public static bool SetUI;

			public static GameObject SuitPanel;

			public static void HookStartGame()
			{
				allSuits = (from suit in Resources.FindObjectsOfTypeAll<UnlockableSuit>()
					orderby suit.syncedSuitID.Value
					select suit).ToArray();
				Object.Instantiate<GameObject>(suitSelectBundle.LoadAsset<GameObject>("SuitSelect"));
				SuitPanel = GameObject.Find("SuitPanel");
				SuitPanel.SetActive(false);
				SetUI = true;
			}

			public static void HookDisconnected()
			{
				currentPage = 0;
			}
		}

		private readonly Harmony Harmony = new Harmony("TooManySuits");

		private InputAction moveRightAction;

		private InputAction moveLeftAction;

		private static int currentPage;

		private int suitsPerPage = 13;

		private int suitsLength;

		private static UnlockableSuit[] allSuits;

		private static AssetBundle suitSelectBundle;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			Plugin.LogSource.LogInfo((object)"TooManySuits Mod Loaded.");
			moveRightAction = new InputAction((string)null, (InputActionType)0, Plugin.NextButton.Value, (string)null, (string)null, (string)null);
			moveRightAction.performed += MoveRightAction;
			moveRightAction.Enable();
			moveLeftAction = new InputAction((string)null, (InputActionType)0, Plugin.BackButton.Value, (string)null, (string)null, (string)null);
			moveLeftAction.performed += MoveLeftAction;
			moveLeftAction.Enable();
			MethodInfo method = typeof(StartOfRound).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method2 = typeof(Hooks).GetMethod("HookStartGame");
			Harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo method3 = typeof(GameNetworkManager).GetMethod("Disconnect");
			MethodInfo method4 = typeof(Hooks).GetMethod("HookDisconnected");
			Harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo method5 = typeof(PlayerControllerB).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method6 = typeof(LocalPlayer).GetMethod("PlayerControllerStart");
			Harmony.Patch((MethodBase)method5, (HarmonyMethod)null, new HarmonyMethod(method6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			suitSelectBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "suitselect"));
			if (MoreSuitsMod.MakeSuitsFitOnRack)
			{
				suitsPerPage = 20;
			}
		}

		private void Update()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null) && allSuits.Length != 0)
			{
				DisplaySuits();
			}
		}

		private void DisplaySuits()
		{
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (allSuits.Length == 0)
			{
				return;
			}
			int num = currentPage * suitsPerPage;
			int num2 = Mathf.Min(num + suitsPerPage, allSuits.Length);
			int num3 = 0;
			for (int i = 0; i < allSuits.Length; i++)
			{
				UnlockableSuit val = allSuits[i];
				AutoParentToShip component = ((Component)val).gameObject.GetComponent<AutoParentToShip>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				bool flag = i >= num && i < num2;
				((Component)val).gameObject.SetActive(flag);
				if (flag)
				{
					component.overrideOffset = true;
					if (MoreSuitsMod.MakeSuitsFitOnRack && suitsLength > 13)
					{
						float num4 = 0.18f;
						num4 /= (float)Math.Min(suitsLength, 20) / 12f;
						component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + StartOfRound.Instance.rightmostSuitPosition.forward * (num4 * (float)num3);
						component.rotationOffset = new Vector3(0f, 90f, 0f);
					}
					else
					{
						component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + StartOfRound.Instance.rightmostSuitPosition.forward * (0.18f * (float)num3);
						component.rotationOffset = new Vector3(0f, 90f, 0f);
					}
					num3++;
				}
			}
			suitsLength = allSuits.Length;
			if (!LocalPlayer.isActive())
			{
				return;
			}
			if (LocalPlayer.localPlayer.isInHangarShipRoom)
			{
				((TMP_Text)Hooks.SuitPanel.GetComponentInChildren<TextMeshProUGUI>()).text = $"Page {currentPage + 1}/{Mathf.CeilToInt((float)suitsLength / (float)suitsPerPage)}";
				Hooks.SuitPanel.SetActive(true);
				return;
			}
			Hooks.SuitPanel.SetActive(false);
			if (Hooks.SetUI)
			{
				Hooks.SetUI = false;
				Hooks.SuitPanel.GetComponentInParent<Canvas>().renderMode = (RenderMode)2;
				Hooks.SuitPanel.GetComponentInParent<Canvas>().worldCamera = LocalPlayer.localPlayer.gameplayCamera;
				Transform transform = Hooks.SuitPanel.transform;
				Bounds bounds = StartOfRound.Instance.shipBounds.bounds;
				transform.position = ((Bounds)(ref bounds)).center - new Vector3(2.8992f, 0.7998f, 2f);
				Hooks.SuitPanel.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
				Hooks.SuitPanel.transform.localScale = new Vector3(Plugin.TextScale.Value, Plugin.TextScale.Value, Plugin.TextScale.Value);
				Hooks.SuitPanel.SetActive(true);
			}
		}

		private void MoveRightAction(CallbackContext obj)
		{
			currentPage = Mathf.Min(currentPage + 1, Mathf.CeilToInt((float)suitsLength / (float)suitsPerPage) - 1);
		}

		private void MoveLeftAction(CallbackContext obj)
		{
			currentPage = Mathf.Max(currentPage - 1, 0);
		}
	}
}
namespace TooManySuits.Helper
{
	public class LocalPlayer
	{
		public static PlayerControllerB localPlayer;

		public static bool isActive()
		{
			return (Object)(object)localPlayer != (Object)null;
		}

		public static void PlayerControllerStart(PlayerControllerB __instance)
		{
			if (NetworkManager.Singleton.LocalClientId == __instance.playerClientId)
			{
				localPlayer = __instance;
			}
		}
	}
}

BepInEx/plugins/SkinwalkerMod.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance.Config;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SkinwalkerMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SkinwalkerMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fd4979a2-cef0-46af-8bf8-97e630b11475")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
	}
}
namespace SkinwalkerMod;

[BepInPlugin("RugbugRedfern.SkinwalkerMod", "Skinwalker Mod", "1.0.8")]
internal class PluginLoader : BaseUnityPlugin
{
	private readonly Harmony harmony = new Harmony("RugbugRedfern.SkinwalkerMod");

	private const string modGUID = "RugbugRedfern.SkinwalkerMod";

	private const string modVersion = "1.0.8";

	private static bool initialized;

	public static PluginLoader Instance { get; private set; }

	private void Awake()
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		if (initialized)
		{
			return;
		}
		initialized = true;
		Instance = this;
		harmony.PatchAll(Assembly.GetExecutingAssembly());
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		Type[] array = types;
		foreach (Type type in array)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
			MethodInfo[] array2 = methods;
			foreach (MethodInfo methodInfo in array2)
			{
				object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
				if (customAttributes.Length != 0)
				{
					methodInfo.Invoke(null, null);
				}
			}
		}
		SkinwalkerLogger.Initialize("RugbugRedfern.SkinwalkerMod");
		SkinwalkerLogger.Log("SKINWALKER MOD STARTING UP 1.0.8");
		SkinwalkerConfig.InitConfig();
		SceneManager.sceneLoaded += SkinwalkerNetworkManagerHandler.ClientConnectInitializer;
		GameObject val = new GameObject("Skinwalker Mod");
		val.AddComponent<SkinwalkerModPersistent>();
		((Object)val).hideFlags = (HideFlags)61;
		Object.DontDestroyOnLoad((Object)(object)val);
	}

	public void BindConfig<T>(ref ConfigEntry<T> config, string section, string key, T defaultValue, string description = "")
	{
		config = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
	}
}
internal class SkinwalkerBehaviour : MonoBehaviour
{
	private AudioSource audioSource;

	public const float PLAY_INTERVAL_MIN = 15f;

	public const float PLAY_INTERVAL_MAX = 40f;

	private const float MAX_DIST = 100f;

	private float nextTimeToPlayAudio;

	private EnemyAI ai;

	public void Initialize(EnemyAI ai)
	{
		this.ai = ai;
		audioSource = ai.creatureVoice;
		SetNextTime();
	}

	private void Update()
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if (!(Time.time > nextTimeToPlayAudio))
		{
			return;
		}
		SetNextTime();
		float num = -1f;
		if (Object.op_Implicit((Object)(object)ai) && !ai.isEnemyDead)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || (num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)this).transform.position)) < 100f)
			{
				AudioClip sample = SkinwalkerModPersistent.Instance.GetSample();
				if (Object.op_Implicit((Object)(object)sample))
				{
					SkinwalkerLogger.Log(((Object)this).name + " played voice line 1");
					audioSource.PlayOneShot(sample);
				}
				else
				{
					SkinwalkerLogger.Log(((Object)this).name + " played voice line 0");
				}
			}
			else
			{
				SkinwalkerLogger.Log(((Object)this).name + " played voice line no (too far away) " + num);
			}
		}
		else
		{
			SkinwalkerLogger.Log(((Object)this).name + " played voice line no (dead) EnemyAI: " + (object)ai);
		}
	}

	private void SetNextTime()
	{
		if (SkinwalkerNetworkManager.Instance.VoiceLineFrequency.Value <= 0f)
		{
			nextTimeToPlayAudio = Time.time + 100000000f;
		}
		else
		{
			nextTimeToPlayAudio = Time.time + Random.Range(15f, 40f) / SkinwalkerNetworkManager.Instance.VoiceLineFrequency.Value;
		}
	}

	private T CopyComponent<T>(T original, GameObject destination) where T : Component
	{
		Type type = ((object)original).GetType();
		Component val = destination.AddComponent(type);
		FieldInfo[] fields = type.GetFields();
		FieldInfo[] array = fields;
		foreach (FieldInfo fieldInfo in array)
		{
			fieldInfo.SetValue(val, fieldInfo.GetValue(original));
		}
		return (T)(object)((val is T) ? val : null);
	}
}
internal class SkinwalkerConfig
{
	public static ConfigEntry<bool> VoiceEnabled_BaboonHawk;

	public static ConfigEntry<bool> VoiceEnabled_Bracken;

	public static ConfigEntry<bool> VoiceEnabled_BunkerSpider;

	public static ConfigEntry<bool> VoiceEnabled_Centipede;

	public static ConfigEntry<bool> VoiceEnabled_CoilHead;

	public static ConfigEntry<bool> VoiceEnabled_EyelessDog;

	public static ConfigEntry<bool> VoiceEnabled_ForestGiant;

	public static ConfigEntry<bool> VoiceEnabled_GhostGirl;

	public static ConfigEntry<bool> VoiceEnabled_GiantWorm;

	public static ConfigEntry<bool> VoiceEnabled_HoardingBug;

	public static ConfigEntry<bool> VoiceEnabled_Hygrodere;

	public static ConfigEntry<bool> VoiceEnabled_Jester;

	public static ConfigEntry<bool> VoiceEnabled_Masked;

	public static ConfigEntry<bool> VoiceEnabled_Nutcracker;

	public static ConfigEntry<bool> VoiceEnabled_SporeLizard;

	public static ConfigEntry<bool> VoiceEnabled_Thumper;

	public static ConfigEntry<float> VoiceLineFrequency;

	public static void InitConfig()
	{
		PluginLoader.Instance.BindConfig(ref VoiceLineFrequency, "Voice Settings", "VoiceLineFrequency", 1f, "1 is the default, and voice lines will occur every " + 15f.ToString("0") + " to " + 40f.ToString("0") + " seconds per enemy. Setting this to 2 means they will occur twice as often, 0.5 means half as often, etc.");
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_BaboonHawk, "Monster Voices", "Baboon Hawk", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Bracken, "Monster Voices", "Bracken", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_BunkerSpider, "Monster Voices", "Bunker Spider", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Centipede, "Monster Voices", "Centipede", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_CoilHead, "Monster Voices", "Coil Head", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_EyelessDog, "Monster Voices", "Eyeless Dog", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_ForestGiant, "Monster Voices", "Forest Giant", defaultValue: false);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_GhostGirl, "Monster Voices", "Ghost Girl", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_GiantWorm, "Monster Voices", "Giant Worm", defaultValue: false);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_HoardingBug, "Monster Voices", "Hoarding Bug", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Hygrodere, "Monster Voices", "Hygrodere", defaultValue: false);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Jester, "Monster Voices", "Jester", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Masked, "Monster Voices", "Masked", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Nutcracker, "Monster Voices", "Nutcracker", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_SporeLizard, "Monster Voices", "Spore Lizard", defaultValue: true);
		PluginLoader.Instance.BindConfig(ref VoiceEnabled_Thumper, "Monster Voices", "Thumper", defaultValue: true);
		SkinwalkerLogger.Log("VoiceEnabled_BaboonHawk" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_BaboonHawk.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Bracken" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Bracken.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_BunkerSpider" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_BunkerSpider.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Centipede" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Centipede.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_CoilHead" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_CoilHead.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_EyelessDog" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_EyelessDog.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_ForestGiant" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_ForestGiant.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_GhostGirl" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_GhostGirl.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_GiantWorm" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_GiantWorm.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_HoardingBug" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_HoardingBug.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Hygrodere" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Hygrodere.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Jester" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Jester.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Masked" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Masked.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Nutcracker" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Nutcracker.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_SporeLizard" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_SporeLizard.Value}]");
		SkinwalkerLogger.Log("VoiceEnabled_Thumper" + $" VALUE LOADED FROM CONFIG: [{VoiceEnabled_Thumper.Value}]");
		SkinwalkerLogger.Log("VoiceLineFrequency" + $" VALUE LOADED FROM CONFIG: [{VoiceLineFrequency.Value}]");
	}
}
internal static class SkinwalkerLogger
{
	internal static ManualLogSource logSource;

	public static void Initialize(string modGUID)
	{
		logSource = Logger.CreateLogSource(modGUID);
	}

	public static void Log(object message)
	{
		logSource.LogInfo(message);
	}

	public static void LogError(object message)
	{
		logSource.LogError(message);
	}

	public static void LogWarning(object message)
	{
		logSource.LogWarning(message);
	}
}
public class SkinwalkerModPersistent : MonoBehaviour
{
	private string audioFolder;

	private List<AudioClip> cachedAudio = new List<AudioClip>();

	private float nextTimeToCheckFolder = 30f;

	private float nextTimeToCheckEnemies = 30f;

	private const float folderScanInterval = 8f;

	private const float enemyScanInterval = 5f;

	public static SkinwalkerModPersistent Instance { get; private set; }

	private void Awake()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		((Component)this).transform.position = Vector3.zero;
		SkinwalkerLogger.Log("Skinwalker Mod Object Initialized");
		audioFolder = Path.Combine(Application.dataPath, "..", "Dissonance_Diagnostics");
		EnableRecording();
		if (!Directory.Exists(audioFolder))
		{
			Directory.CreateDirectory(audioFolder);
		}
	}

	private void Start()
	{
		try
		{
			if (Directory.Exists(audioFolder))
			{
				Directory.Delete(audioFolder, recursive: true);
			}
		}
		catch (Exception message)
		{
			SkinwalkerLogger.Log(message);
		}
	}

	private void OnApplicationQuit()
	{
		DisableRecording();
	}

	private void EnableRecording()
	{
		DebugSettings.Instance.EnablePlaybackDiagnostics = true;
		DebugSettings.Instance.RecordFinalAudio = true;
	}

	private void Update()
	{
		if (Time.realtimeSinceStartup > nextTimeToCheckFolder)
		{
			nextTimeToCheckFolder = Time.realtimeSinceStartup + 8f;
			if (!Directory.Exists(audioFolder))
			{
				SkinwalkerLogger.Log("Audio folder not present. Don't worry about it, it will be created automatically when you play with friends. (" + audioFolder + ")");
				return;
			}
			string[] files = Directory.GetFiles(audioFolder);
			SkinwalkerLogger.Log($"Got audio file paths ({files.Length})");
			string[] array = files;
			foreach (string path in array)
			{
				((MonoBehaviour)this).StartCoroutine(LoadWavFile(path, delegate(AudioClip audioClip)
				{
					cachedAudio.Add(audioClip);
				}));
			}
		}
		if (!(Time.realtimeSinceStartup > nextTimeToCheckEnemies))
		{
			return;
		}
		nextTimeToCheckEnemies = Time.realtimeSinceStartup + 5f;
		EnemyAI[] array2 = Object.FindObjectsOfType<EnemyAI>(true);
		EnemyAI[] array3 = array2;
		SkinwalkerBehaviour skinwalkerBehaviour = default(SkinwalkerBehaviour);
		foreach (EnemyAI val in array3)
		{
			SkinwalkerLogger.Log("IsEnemyEnabled " + ((Object)val).name + " " + IsEnemyEnabled(val));
			if (IsEnemyEnabled(val) && !((Component)val).TryGetComponent<SkinwalkerBehaviour>(ref skinwalkerBehaviour))
			{
				((Component)val).gameObject.AddComponent<SkinwalkerBehaviour>().Initialize(val);
			}
		}
	}

	private bool IsEnemyEnabled(EnemyAI enemy)
	{
		if ((Object)(object)enemy == (Object)null)
		{
			return false;
		}
		return ((Object)((Component)enemy).gameObject).name switch
		{
			"MaskedPlayerEnemy(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Masked.Value, 
			"NutcrackerEnemy(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Nutcracker.Value, 
			"BaboonHawkEnemy(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_BaboonHawk.Value, 
			"Flowerman(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Bracken.Value, 
			"SandSpider(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_BunkerSpider.Value, 
			"RedLocustBees(Clone)" => false, 
			"Centipede(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Centipede.Value, 
			"SpringMan(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_CoilHead.Value, 
			"MouthDog(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_EyelessDog.Value, 
			"ForestGiant(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_ForestGiant.Value, 
			"DressGirl(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_GhostGirl.Value, 
			"SandWorm(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_GiantWorm.Value, 
			"HoarderBug(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_HoardingBug.Value, 
			"Blob(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Hygrodere.Value, 
			"JesterEnemy(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Jester.Value, 
			"PufferEnemy(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_SporeLizard.Value, 
			"Crawler(Clone)" => SkinwalkerNetworkManager.Instance.VoiceEnabled_Thumper.Value, 
			"DocileLocustBees(Clone)" => false, 
			"DoublewingedBird(Clone)" => false, 
			_ => true, 
		};
	}

	internal IEnumerator LoadWavFile(string path, Action<AudioClip> callback)
	{
		UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)20);
		try
		{
			yield return www.SendWebRequest();
			if ((int)www.result == 1)
			{
				SkinwalkerLogger.Log("Loaded clip from path " + path);
				AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
				if (audioClip.length > 0.9f)
				{
					callback(audioClip);
				}
				try
				{
					File.Delete(path);
				}
				catch (Exception e)
				{
					SkinwalkerLogger.LogWarning(e);
				}
			}
		}
		finally
		{
			((IDisposable)www)?.Dispose();
		}
	}

	private void DisableRecording()
	{
		DebugSettings.Instance.EnablePlaybackDiagnostics = false;
		DebugSettings.Instance.RecordFinalAudio = false;
		if (Directory.Exists(audioFolder))
		{
			Directory.Delete(audioFolder, recursive: true);
		}
	}

	public AudioClip GetSample()
	{
		if (cachedAudio.Count > 0)
		{
			int index = Random.Range(0, cachedAudio.Count - 1);
			AudioClip result = cachedAudio[index];
			cachedAudio.RemoveAt(index);
			return result;
		}
		while (cachedAudio.Count > 200)
		{
			cachedAudio.RemoveAt(0);
		}
		return null;
	}

	public void ClearCache()
	{
		cachedAudio.Clear();
	}
}
internal static class SkinwalkerNetworkManagerHandler
{
	internal static void ClientConnectInitializer(Scene sceneName, LoadSceneMode sceneEnum)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		if (((Scene)(ref sceneName)).name == "SampleSceneRelay")
		{
			GameObject val = new GameObject("SkinwalkerNetworkManager");
			val.AddComponent<NetworkObject>();
			val.AddComponent<SkinwalkerNetworkManager>();
			Debug.Log((object)"Initialized SkinwalkerNetworkManager");
		}
	}
}
internal class SkinwalkerNetworkManager : NetworkBehaviour
{
	public NetworkVariable<bool> VoiceEnabled_BaboonHawk = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Bracken = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_BunkerSpider = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Centipede = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_CoilHead = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_EyelessDog = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_ForestGiant = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_GhostGirl = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_GiantWorm = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_HoardingBug = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Hygrodere = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Jester = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Masked = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Nutcracker = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_SporeLizard = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> VoiceEnabled_Thumper = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<float> VoiceLineFrequency = new NetworkVariable<float>(1f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public static SkinwalkerNetworkManager Instance { get; private set; }

	private void Awake()
	{
		Instance = this;
		if (GameNetworkManager.Instance.isHostingGame)
		{
			VoiceEnabled_BaboonHawk.Value = SkinwalkerConfig.VoiceEnabled_BaboonHawk.Value;
			VoiceEnabled_Bracken.Value = SkinwalkerConfig.VoiceEnabled_Bracken.Value;
			VoiceEnabled_BunkerSpider.Value = SkinwalkerConfig.VoiceEnabled_BunkerSpider.Value;
			VoiceEnabled_Centipede.Value = SkinwalkerConfig.VoiceEnabled_Centipede.Value;
			VoiceEnabled_CoilHead.Value = SkinwalkerConfig.VoiceEnabled_CoilHead.Value;
			VoiceEnabled_EyelessDog.Value = SkinwalkerConfig.VoiceEnabled_EyelessDog.Value;
			VoiceEnabled_ForestGiant.Value = SkinwalkerConfig.VoiceEnabled_ForestGiant.Value;
			VoiceEnabled_GhostGirl.Value = SkinwalkerConfig.VoiceEnabled_GhostGirl.Value;
			VoiceEnabled_GiantWorm.Value = SkinwalkerConfig.VoiceEnabled_GiantWorm.Value;
			VoiceEnabled_HoardingBug.Value = SkinwalkerConfig.VoiceEnabled_HoardingBug.Value;
			VoiceEnabled_Hygrodere.Value = SkinwalkerConfig.VoiceEnabled_Hygrodere.Value;
			VoiceEnabled_Jester.Value = SkinwalkerConfig.VoiceEnabled_Jester.Value;
			VoiceEnabled_Masked.Value = SkinwalkerConfig.VoiceEnabled_Masked.Value;
			VoiceEnabled_Nutcracker.Value = SkinwalkerConfig.VoiceEnabled_Nutcracker.Value;
			VoiceEnabled_SporeLizard.Value = SkinwalkerConfig.VoiceEnabled_SporeLizard.Value;
			VoiceEnabled_Thumper.Value = SkinwalkerConfig.VoiceEnabled_Thumper.Value;
			VoiceLineFrequency.Value = SkinwalkerConfig.VoiceLineFrequency.Value;
			SkinwalkerLogger.Log("HOST SENDING CONFIG TO CLIENTS");
		}
		SkinwalkerLogger.Log("SkinwalkerNetworkManager Awake");
	}

	public override void OnDestroy()
	{
		((NetworkBehaviour)this).OnDestroy();
		SkinwalkerLogger.Log("SkinwalkerNetworkManager OnDestroy");
		SkinwalkerModPersistent.Instance?.ClearCache();
	}

	protected override void __initializeVariables()
	{
		if (VoiceEnabled_BaboonHawk == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_BaboonHawk cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_BaboonHawk).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_BaboonHawk, "VoiceEnabled_BaboonHawk");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_BaboonHawk);
		if (VoiceEnabled_Bracken == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Bracken cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Bracken).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Bracken, "VoiceEnabled_Bracken");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Bracken);
		if (VoiceEnabled_BunkerSpider == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_BunkerSpider cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_BunkerSpider).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_BunkerSpider, "VoiceEnabled_BunkerSpider");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_BunkerSpider);
		if (VoiceEnabled_Centipede == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Centipede cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Centipede).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Centipede, "VoiceEnabled_Centipede");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Centipede);
		if (VoiceEnabled_CoilHead == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_CoilHead cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_CoilHead).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_CoilHead, "VoiceEnabled_CoilHead");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_CoilHead);
		if (VoiceEnabled_EyelessDog == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_EyelessDog cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_EyelessDog).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_EyelessDog, "VoiceEnabled_EyelessDog");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_EyelessDog);
		if (VoiceEnabled_ForestGiant == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_ForestGiant cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_ForestGiant).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_ForestGiant, "VoiceEnabled_ForestGiant");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_ForestGiant);
		if (VoiceEnabled_GhostGirl == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_GhostGirl cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_GhostGirl).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_GhostGirl, "VoiceEnabled_GhostGirl");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_GhostGirl);
		if (VoiceEnabled_GiantWorm == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_GiantWorm cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_GiantWorm).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_GiantWorm, "VoiceEnabled_GiantWorm");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_GiantWorm);
		if (VoiceEnabled_HoardingBug == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_HoardingBug cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_HoardingBug).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_HoardingBug, "VoiceEnabled_HoardingBug");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_HoardingBug);
		if (VoiceEnabled_Hygrodere == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Hygrodere cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Hygrodere).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Hygrodere, "VoiceEnabled_Hygrodere");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Hygrodere);
		if (VoiceEnabled_Jester == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Jester cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Jester).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Jester, "VoiceEnabled_Jester");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Jester);
		if (VoiceEnabled_Masked == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Masked cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Masked).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Masked, "VoiceEnabled_Masked");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Masked);
		if (VoiceEnabled_Nutcracker == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Nutcracker cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Nutcracker).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Nutcracker, "VoiceEnabled_Nutcracker");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Nutcracker);
		if (VoiceEnabled_SporeLizard == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_SporeLizard cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_SporeLizard).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_SporeLizard, "VoiceEnabled_SporeLizard");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_SporeLizard);
		if (VoiceEnabled_Thumper == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceEnabled_Thumper cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceEnabled_Thumper).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceEnabled_Thumper, "VoiceEnabled_Thumper");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceEnabled_Thumper);
		if (VoiceLineFrequency == null)
		{
			throw new Exception("SkinwalkerNetworkManager.VoiceLineFrequency cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)VoiceLineFrequency).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VoiceLineFrequency, "VoiceLineFrequency");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)VoiceLineFrequency);
		((NetworkBehaviour)this).__initializeVariables();
	}

	protected internal override string __getTypeName()
	{
		return "SkinwalkerNetworkManager";
	}
}

BepInEx/plugins/MoreCompany.dll

Decompiled 8 months 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.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using MoreCompany.Cosmetics;
using MoreCompany.Utils;
using Steamworks;
using Steamworks.Data;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MoreCompany")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreCompany")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("511a1e5e-0611-49f1-b60f-cec69c668fd8")]
[assembly: AssemblyFileVersion("1.7.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.7.2.0")]
namespace MoreCompany
{
	[HarmonyPatch(typeof(AudioMixer), "SetFloat")]
	public static class AudioMixerSetFloatPatch
	{
		public static bool Prefix(string name, float value)
		{
			if (name.StartsWith("PlayerVolume") || name.StartsWith("PlayerPitch"))
			{
				string s = name.Replace("PlayerVolume", "").Replace("PlayerPitch", "");
				int num = int.Parse(s);
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[num];
				AudioSource currentVoiceChatAudioSource = val.currentVoiceChatAudioSource;
				if ((Object)(object)val != (Object)null && Object.op_Implicit((Object)(object)currentVoiceChatAudioSource))
				{
					if (name.StartsWith("PlayerVolume"))
					{
						currentVoiceChatAudioSource.volume = value / 16f;
					}
					else if (name.StartsWith("PlayerPitch"))
					{
						currentVoiceChatAudioSource.pitch = value;
					}
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddTextToChatOnServer")]
	public static class SendChatToServerPatch
	{
		public static bool Prefix(HUDManager __instance, string chatMessage, int playerId = -1)
		{
			if (((NetworkBehaviour)StartOfRound.Instance).IsHost && chatMessage.StartsWith("/mc") && DebugCommandRegistry.commandEnabled)
			{
				string text = chatMessage.Replace("/mc ", "");
				DebugCommandRegistry.HandleCommand(text.Split(new char[1] { ' ' }));
				return false;
			}
			if (chatMessage.StartsWith("[morecompanycosmetics]"))
			{
				ReflectionUtils.InvokeMethod(__instance, "AddPlayerChatMessageServerRpc", new object[2] { chatMessage, 99 });
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")]
	public static class ServerReceiveMessagePatch
	{
		public static string previousDataMessage = "";

		public static bool Prefix(HUDManager __instance, ref string chatMessage, int playerId)
		{
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return false;
			}
			if (chatMessage.StartsWith("[morecompanycosmetics]") && networkManager.IsServer)
			{
				previousDataMessage = chatMessage;
				chatMessage = "[replacewithdata]";
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
	public static class ConnectClientToPlayerObjectPatch
	{
		public static void Postfix(PlayerControllerB __instance)
		{
			string text = "[morecompanycosmetics]";
			text = text + ";" + __instance.playerClientId;
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				text = text + ";" + locallySelectedCosmetic;
			}
			HUDManager.Instance.AddTextToChatOnServer(text, -1);
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddChatMessage")]
	public static class AddChatMessagePatch
	{
		public static bool Prefix(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped = "")
		{
			if (chatMessage.StartsWith("[replacewithdata]") || chatMessage.StartsWith("[morecompanycosmetics]"))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
	public static class ClientReceiveMessagePatch
	{
		public static bool ignoreSample;

		public static bool Prefix(HUDManager __instance, ref string chatMessage, int playerId)
		{
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return false;
			}
			if (networkManager.IsServer)
			{
				if (chatMessage.StartsWith("[replacewithdata]"))
				{
					chatMessage = ServerReceiveMessagePatch.previousDataMessage;
					HandleDataMessage(chatMessage);
				}
				else if (chatMessage.StartsWith("[morecompanycosmetics]"))
				{
					return false;
				}
			}
			else if (chatMessage.StartsWith("[morecompanycosmetics]"))
			{
				HandleDataMessage(chatMessage);
			}
			return true;
		}

		private static void HandleDataMessage(string chatMessage)
		{
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (ignoreSample)
			{
				return;
			}
			chatMessage = chatMessage.Replace("[morecompanycosmetics]", "");
			string[] array = chatMessage.Split(new char[1] { ';' });
			string text = array[1];
			int num = int.Parse(text);
			CosmeticApplication component = ((Component)((Component)StartOfRound.Instance.allPlayerScripts[num]).transform.Find("ScavengerModel").Find("metarig")).gameObject.GetComponent<CosmeticApplication>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.ClearCosmetics();
				Object.Destroy((Object)(object)component);
			}
			CosmeticApplication cosmeticApplication = ((Component)((Component)StartOfRound.Instance.allPlayerScripts[num]).transform.Find("ScavengerModel").Find("metarig")).gameObject.AddComponent<CosmeticApplication>();
			cosmeticApplication.ClearCosmetics();
			List<string> list = new List<string>();
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (!(text2 == text))
				{
					list.Add(text2);
					if (MainClass.showCosmetics)
					{
						cosmeticApplication.ApplyCosmetic(text2, startEnabled: true);
					}
				}
			}
			if (num == StartOfRound.Instance.thisClientPlayerId)
			{
				cosmeticApplication.ClearCosmetics();
			}
			foreach (CosmeticInstance spawnedCosmetic in cosmeticApplication.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
			}
			MainClass.playerIdsAndCosmetics.Remove(num);
			MainClass.playerIdsAndCosmetics.Add(num, list);
			if (!GameNetworkManager.Instance.isHostingGame || num == 0)
			{
				return;
			}
			ignoreSample = true;
			foreach (KeyValuePair<int, List<string>> playerIdsAndCosmetic in MainClass.playerIdsAndCosmetics)
			{
				string text3 = "[morecompanycosmetics]";
				text3 = text3 + ";" + playerIdsAndCosmetic.Key;
				foreach (string item in playerIdsAndCosmetic.Value)
				{
					text3 = text3 + ";" + item;
				}
				HUDManager.Instance.AddTextToChatOnServer(text3, -1);
			}
			ignoreSample = false;
		}
	}
	public class DebugCommandRegistry
	{
		public static bool commandEnabled;

		public static void HandleCommand(string[] args)
		{
			//IL_00cc: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			if (!commandEnabled)
			{
				return;
			}
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			switch (args[0])
			{
			case "money":
			{
				int groupCredits = int.Parse(args[1]);
				Terminal val5 = Resources.FindObjectsOfTypeAll<Terminal>().First();
				val5.groupCredits = groupCredits;
				break;
			}
			case "spawnscrap":
			{
				string text = "";
				for (int i = 1; i < args.Length; i++)
				{
					text = text + args[i] + " ";
				}
				text = text.Trim();
				Vector3 val = ((Component)localPlayerController).transform.position + ((Component)localPlayerController).transform.forward * 2f;
				SpawnableItemWithRarity val2 = null;
				foreach (SpawnableItemWithRarity item in StartOfRound.Instance.currentLevel.spawnableScrap)
				{
					if (item.spawnableItem.itemName.ToLower() == text.ToLower())
					{
						val2 = item;
						break;
					}
				}
				GameObject val3 = Object.Instantiate<GameObject>(val2.spawnableItem.spawnPrefab, val, Quaternion.identity, (Transform)null);
				GrabbableObject component = val3.GetComponent<GrabbableObject>();
				((Component)component).transform.rotation = Quaternion.Euler(component.itemProperties.restingRotation);
				component.fallTime = 0f;
				NetworkObject component2 = val3.GetComponent<NetworkObject>();
				component2.Spawn(false);
				break;
			}
			case "spawnenemy":
			{
				string text2 = "";
				for (int j = 1; j < args.Length; j++)
				{
					text2 = text2 + args[j] + " ";
				}
				text2 = text2.Trim();
				SpawnableEnemyWithRarity val4 = null;
				foreach (SpawnableEnemyWithRarity enemy in StartOfRound.Instance.currentLevel.Enemies)
				{
					if (enemy.enemyType.enemyName.ToLower() == text2.ToLower())
					{
						val4 = enemy;
						break;
					}
				}
				RoundManager.Instance.SpawnEnemyGameObject(((Component)localPlayerController).transform.position + ((Component)localPlayerController).transform.forward * 2f, 0f, -1, val4.enemyType);
				break;
			}
			case "listall":
				MainClass.StaticLogger.LogInfo((object)"Spawnable scrap:");
				foreach (SpawnableItemWithRarity item2 in StartOfRound.Instance.currentLevel.spawnableScrap)
				{
					MainClass.StaticLogger.LogInfo((object)item2.spawnableItem.itemName);
				}
				MainClass.StaticLogger.LogInfo((object)"Spawnable enemies:");
				{
					foreach (SpawnableEnemyWithRarity enemy2 in StartOfRound.Instance.currentLevel.Enemies)
					{
						MainClass.StaticLogger.LogInfo((object)enemy2.enemyType.enemyName);
					}
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ForestGiantAI), "LookForPlayers")]
	public static class LookForPlayersForestGiantPatch
	{
		public static void Prefix(ForestGiantAI __instance)
		{
			if (__instance.playerStealthMeters.Length != MainClass.newPlayerCount)
			{
				__instance.playerStealthMeters = new float[MainClass.newPlayerCount];
				for (int i = 0; i < MainClass.newPlayerCount; i++)
				{
					__instance.playerStealthMeters[i] = 0f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SpringManAI), "Update")]
	public static class SpringManAIUpdatePatch
	{
		public static bool Prefix(SpringManAI __instance, ref float ___timeSinceHittingPlayer, ref float ___stopAndGoMinimumInterval, ref bool ___wasOwnerLastFrame, ref bool ___stoppingMovement, ref float ___currentChaseSpeed, ref bool ___hasStopped, ref float ___currentAnimSpeed, ref float ___updateDestinationInterval, ref Vector3 ___tempVelocity, ref float ___targetYRotation, ref float ___setDestinationToPlayerInterval, ref float ___previousYRotation)
		{
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			UpdateBase((EnemyAI)(object)__instance, ref ___updateDestinationInterval, ref ___tempVelocity, ref ___targetYRotation, ref ___setDestinationToPlayerInterval, ref ___previousYRotation);
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			int currentBehaviourStateIndex = ((EnemyAI)__instance).currentBehaviourStateIndex;
			if (currentBehaviourStateIndex != 0 && currentBehaviourStateIndex == 1)
			{
				if (___timeSinceHittingPlayer >= 0f)
				{
					___timeSinceHittingPlayer -= Time.deltaTime;
				}
				if (((NetworkBehaviour)__instance).IsOwner)
				{
					if (___stopAndGoMinimumInterval > 0f)
					{
						___stopAndGoMinimumInterval -= Time.deltaTime;
					}
					if (!___wasOwnerLastFrame)
					{
						___wasOwnerLastFrame = true;
						if (!___stoppingMovement && ___timeSinceHittingPlayer < 0.12f)
						{
							((EnemyAI)__instance).agent.speed = ___currentChaseSpeed;
						}
						else
						{
							((EnemyAI)__instance).agent.speed = 0f;
						}
					}
					bool flag = false;
					for (int i = 0; i < MainClass.newPlayerCount; i++)
					{
						if (((EnemyAI)__instance).PlayerIsTargetable(StartOfRound.Instance.allPlayerScripts[i], false, false) && StartOfRound.Instance.allPlayerScripts[i].HasLineOfSightToPosition(((Component)__instance).transform.position + Vector3.up * 1.6f, 68f, 60, -1f) && Vector3.Distance(((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position, ((EnemyAI)__instance).eye.position) > 0.3f)
						{
							flag = true;
						}
					}
					if (((EnemyAI)__instance).stunNormalizedTimer > 0f)
					{
						flag = true;
					}
					if (flag != ___stoppingMovement && ___stopAndGoMinimumInterval <= 0f)
					{
						___stopAndGoMinimumInterval = 0.15f;
						if (flag)
						{
							__instance.SetAnimationStopServerRpc();
						}
						else
						{
							__instance.SetAnimationGoServerRpc();
						}
						___stoppingMovement = flag;
					}
				}
				if (___stoppingMovement)
				{
					if (__instance.animStopPoints.canAnimationStop)
					{
						if (!___hasStopped)
						{
							___hasStopped = true;
							__instance.mainCollider.isTrigger = false;
							if (GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(((Component)__instance).transform.position, 70f, 25, -1f))
							{
								float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position);
								if (num < 4f)
								{
									GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.9f, true);
								}
								else if (num < 9f)
								{
									GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.4f, true);
								}
							}
							if (___currentAnimSpeed > 2f)
							{
								RoundManager.PlayRandomClip(((EnemyAI)__instance).creatureVoice, __instance.springNoises, false, 1f, 0);
								if (__instance.animStopPoints.animationPosition == 1)
								{
									((EnemyAI)__instance).creatureAnimator.SetTrigger("springBoing");
								}
								else
								{
									((EnemyAI)__instance).creatureAnimator.SetTrigger("springBoingPosition2");
								}
							}
						}
						((EnemyAI)__instance).creatureAnimator.SetFloat("walkSpeed", 0f);
						___currentAnimSpeed = 0f;
						if (((NetworkBehaviour)__instance).IsOwner)
						{
							((EnemyAI)__instance).agent.speed = 0f;
							return false;
						}
					}
				}
				else
				{
					if (___hasStopped)
					{
						___hasStopped = false;
						__instance.mainCollider.isTrigger = true;
					}
					___currentAnimSpeed = Mathf.Lerp(___currentAnimSpeed, 6f, 5f * Time.deltaTime);
					((EnemyAI)__instance).creatureAnimator.SetFloat("walkSpeed", ___currentAnimSpeed);
					if (((NetworkBehaviour)__instance).IsOwner)
					{
						((EnemyAI)__instance).agent.speed = Mathf.Lerp(((EnemyAI)__instance).agent.speed, ___currentChaseSpeed, 4.5f * Time.deltaTime);
					}
				}
			}
			return false;
		}

		private static void UpdateBase(EnemyAI __instance, ref float updateDestinationInterval, ref Vector3 tempVelocity, ref float targetYRotation, ref float setDestinationToPlayerInterval, ref float previousYRotation)
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.enemyType.isDaytimeEnemy && !__instance.daytimeEnemyLeaving)
			{
				ReflectionUtils.InvokeMethod(__instance, typeof(EnemyAI), "CheckTimeOfDayToLeave", null);
			}
			if (__instance.stunnedIndefinitely <= 0)
			{
				if ((double)__instance.stunNormalizedTimer >= 0.0)
				{
					__instance.stunNormalizedTimer -= Time.deltaTime / __instance.enemyType.stunTimeMultiplier;
				}
				else
				{
					__instance.stunnedByPlayer = null;
					if ((double)__instance.postStunInvincibilityTimer >= 0.0)
					{
						__instance.postStunInvincibilityTimer -= Time.deltaTime * 5f;
					}
				}
			}
			if (!__instance.ventAnimationFinished && (double)__instance.timeSinceSpawn < (double)__instance.exitVentAnimationTime + 0.004999999888241291 * (double)RoundManager.Instance.numberOfEnemiesInScene)
			{
				__instance.timeSinceSpawn += Time.deltaTime;
				if (!((NetworkBehaviour)__instance).IsOwner)
				{
					Vector3 serverPosition = __instance.serverPosition;
					if (__instance.serverPosition != Vector3.zero)
					{
						((Component)__instance).transform.position = __instance.serverPosition;
						((Component)__instance).transform.eulerAngles = new Vector3(((Component)__instance).transform.eulerAngles.x, targetYRotation, ((Component)__instance).transform.eulerAngles.z);
					}
				}
				else if ((double)updateDestinationInterval >= 0.0)
				{
					updateDestinationInterval -= Time.deltaTime;
				}
				else
				{
					__instance.SyncPositionToClients();
					updateDestinationInterval = 0.1f;
				}
				return;
			}
			if (!__instance.ventAnimationFinished)
			{
				__instance.ventAnimationFinished = true;
				if ((Object)(object)__instance.creatureAnimator != (Object)null)
				{
					__instance.creatureAnimator.SetBool("inSpawningAnimation", false);
				}
			}
			if (!((NetworkBehaviour)__instance).IsOwner)
			{
				if (__instance.currentSearch.inProgress)
				{
					__instance.StopSearch(__instance.currentSearch, true);
				}
				__instance.SetClientCalculatingAI(false);
				if (!__instance.inSpecialAnimation)
				{
					((Component)__instance).transform.position = Vector3.SmoothDamp(((Component)__instance).transform.position, __instance.serverPosition, ref tempVelocity, __instance.syncMovementSpeed);
					((Component)__instance).transform.eulerAngles = new Vector3(((Component)__instance).transform.eulerAngles.x, Mathf.LerpAngle(((Component)__instance).transform.eulerAngles.y, targetYRotation, 15f * Time.deltaTime), ((Component)__instance).transform.eulerAngles.z);
				}
				__instance.timeSinceSpawn += Time.deltaTime;
				return;
			}
			if (__instance.isEnemyDead)
			{
				__instance.SetClientCalculatingAI(false);
				return;
			}
			if (!__instance.inSpecialAnimation)
			{
				__instance.SetClientCalculatingAI(true);
			}
			if (__instance.movingTowardsTargetPlayer && (Object)(object)__instance.targetPlayer != (Object)null)
			{
				if ((double)setDestinationToPlayerInterval <= 0.0)
				{
					setDestinationToPlayerInterval = 0.25f;
					__instance.destination = RoundManager.Instance.GetNavMeshPosition(((Component)__instance.targetPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1);
				}
				else
				{
					__instance.destination = new Vector3(((Component)__instance.targetPlayer).transform.position.x, __instance.destination.y, ((Component)__instance.targetPlayer).transform.position.z);
					setDestinationToPlayerInterval -= Time.deltaTime;
				}
			}
			if (__instance.inSpecialAnimation)
			{
				return;
			}
			if ((double)updateDestinationInterval >= 0.0)
			{
				updateDestinationInterval -= Time.deltaTime;
			}
			else
			{
				__instance.DoAIInterval();
				updateDestinationInterval = __instance.AIIntervalTime;
			}
			if (!((double)Mathf.Abs(previousYRotation - ((Component)__instance).transform.eulerAngles.y) <= 6.0))
			{
				previousYRotation = ((Component)__instance).transform.eulerAngles.y;
				targetYRotation = previousYRotation;
				if (((NetworkBehaviour)__instance).IsServer)
				{
					ReflectionUtils.InvokeMethod(__instance, typeof(EnemyAI), "UpdateEnemyRotationClientRpc", new object[1] { (short)previousYRotation });
				}
				else
				{
					ReflectionUtils.InvokeMethod(__instance, typeof(EnemyAI), "UpdateEnemyRotationServerRpc", new object[1] { (short)previousYRotation });
				}
			}
		}
	}
	[HarmonyPatch(typeof(SpringManAI), "DoAIInterval")]
	public static class SpringManAIIntervalPatch
	{
		public static bool Prefix(SpringManAI __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			if (((EnemyAI)__instance).moveTowardsDestination)
			{
				((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
			}
			((EnemyAI)__instance).SyncPositionToClients();
			if (StartOfRound.Instance.allPlayersDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			default:
				return false;
			case 1:
				if (__instance.searchForPlayers.inProgress)
				{
					((EnemyAI)__instance).StopSearch(__instance.searchForPlayers, true);
				}
				if (((EnemyAI)__instance).TargetClosestPlayer(1.5f, false, 70f))
				{
					PlayerControllerB fieldValue = ReflectionUtils.GetFieldValue<PlayerControllerB>(__instance, "previousTarget");
					if ((Object)(object)fieldValue != (Object)(object)((EnemyAI)__instance).targetPlayer)
					{
						ReflectionUtils.SetFieldValue(__instance, "previousTarget", ((EnemyAI)__instance).targetPlayer);
						((EnemyAI)__instance).ChangeOwnershipOfEnemy(((EnemyAI)__instance).targetPlayer.actualClientId);
					}
					((EnemyAI)__instance).movingTowardsTargetPlayer = true;
					return false;
				}
				((EnemyAI)__instance).SwitchToBehaviourState(0);
				((EnemyAI)__instance).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId);
				break;
			case 0:
			{
				if (!((NetworkBehaviour)__instance).IsServer)
				{
					((EnemyAI)__instance).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId);
					return false;
				}
				for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
				{
					if (((EnemyAI)__instance).PlayerIsTargetable(StartOfRound.Instance.allPlayerScripts[i], false, false) && !Physics.Linecast(((Component)__instance).transform.position + Vector3.up * 0.5f, ((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault) && Vector3.Distance(((Component)__instance).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) < 30f)
					{
						((EnemyAI)__instance).SwitchToBehaviourState(1);
						return false;
					}
				}
				if (!__instance.searchForPlayers.inProgress)
				{
					((EnemyAI)__instance).movingTowardsTargetPlayer = false;
					((EnemyAI)__instance).StartSearch(((Component)__instance).transform.position, __instance.searchForPlayers);
					return false;
				}
				break;
			}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "GetClosestPlayer")]
	public static class GetClosestPlayerPatch
	{
		public static bool Prefix(EnemyAI __instance, ref PlayerControllerB __result, bool requireLineOfSight = false, bool cannotBeInShip = false, bool cannotBeNearShip = false)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = null;
			__instance.mostOptimalDistance = 2000f;
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				if (!__instance.PlayerIsTargetable(StartOfRound.Instance.allPlayerScripts[i], cannotBeInShip, false))
				{
					continue;
				}
				if (cannotBeNearShip)
				{
					if (StartOfRound.Instance.allPlayerScripts[i].isInElevator)
					{
						continue;
					}
					bool flag = false;
					for (int j = 0; j < RoundManager.Instance.spawnDenialPoints.Length; j++)
					{
						if (Vector3.Distance(RoundManager.Instance.spawnDenialPoints[j].transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) < 10f)
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						continue;
					}
				}
				if (!requireLineOfSight || !Physics.Linecast(((Component)__instance).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position, 256))
				{
					__instance.tempDist = Vector3.Distance(((Component)__instance).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
					if (__instance.tempDist < __instance.mostOptimalDistance)
					{
						__instance.mostOptimalDistance = __instance.tempDist;
						val = StartOfRound.Instance.allPlayerScripts[i];
					}
				}
			}
			__result = val;
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "GetAllPlayersInLineOfSight")]
	public static class GetAllPlayersInLineOfSightPatch
	{
		public static bool Prefix(EnemyAI __instance, ref PlayerControllerB[] __result, float width = 45f, int range = 60, Transform eyeObject = null, float proximityCheck = -1f, int layerMask = -1)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_00b3: 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_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_00d2: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			if (layerMask == -1)
			{
				layerMask = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			}
			if ((Object)(object)eyeObject == (Object)null)
			{
				eyeObject = __instance.eye;
			}
			if (__instance.enemyType.isOutsideEnemy && !__instance.enemyType.canSeeThroughFog && (int)TimeOfDay.Instance.currentLevelWeather == 3)
			{
				range = Mathf.Clamp(range, 0, 30);
			}
			List<PlayerControllerB> list = new List<PlayerControllerB>(MainClass.newPlayerCount);
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				if (!__instance.PlayerIsTargetable(StartOfRound.Instance.allPlayerScripts[i], false, false))
				{
					continue;
				}
				Vector3 position = ((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position;
				if (Vector3.Distance(__instance.eye.position, position) < (float)range && !Physics.Linecast(eyeObject.position, position, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
				{
					Vector3 val = position - eyeObject.position;
					if (Vector3.Angle(eyeObject.forward, val) < width || Vector3.Distance(((Component)__instance).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) < proximityCheck)
					{
						list.Add(StartOfRound.Instance.allPlayerScripts[i]);
					}
				}
			}
			if (list.Count == MainClass.newPlayerCount)
			{
				__result = StartOfRound.Instance.allPlayerScripts;
				return false;
			}
			if (list.Count > 0)
			{
				__result = list.ToArray();
				return false;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(DressGirlAI), "ChoosePlayerToHaunt")]
	public static class DressGirlHauntPatch
	{
		public static bool Prefix(DressGirlAI __instance)
		{
			ReflectionUtils.SetFieldValue(__instance, "timesChoosingAPlayer", ReflectionUtils.GetFieldValue<int>(__instance, "timesChoosingAPlayer") + 1);
			if (ReflectionUtils.GetFieldValue<int>(__instance, "timesChoosingAPlayer") > 1)
			{
				__instance.timer = __instance.hauntInterval - 1f;
			}
			__instance.SFXVolumeLerpTo = 0f;
			((EnemyAI)__instance).creatureVoice.Stop();
			__instance.heartbeatMusic.volume = 0f;
			if (!ReflectionUtils.GetFieldValue<bool>(__instance, "initializedRandomSeed"))
			{
				ReflectionUtils.SetFieldValue(__instance, "ghostGirlRandom", new Random(StartOfRound.Instance.randomMapSeed + 158));
			}
			float num = 0f;
			float num2 = 0f;
			int num3 = 0;
			int num4 = 0;
			for (int i = 0; i < MainClass.newPlayerCount; i++)
			{
				if (StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount > num3)
				{
					num3 = StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount;
					num4 = i;
				}
				if (StartOfRound.Instance.allPlayerScripts[i].insanityLevel > num)
				{
					num = StartOfRound.Instance.allPlayerScripts[i].insanityLevel;
					num2 = i;
				}
			}
			int[] array = new int[MainClass.newPlayerCount];
			for (int j = 0; j < MainClass.newPlayerCount; j++)
			{
				if (!StartOfRound.Instance.allPlayerScripts[j].isPlayerControlled)
				{
					array[j] = 0;
					continue;
				}
				array[j] += 80;
				if (num2 == (float)j && num > 1f)
				{
					array[j] += 50;
				}
				if (num4 == j)
				{
					array[j] += 30;
				}
				if (!StartOfRound.Instance.allPlayerScripts[j].hasBeenCriticallyInjured)
				{
					array[j] += 10;
				}
				if ((Object)(object)StartOfRound.Instance.allPlayerScripts[j].currentlyHeldObjectServer != (Object)null && StartOfRound.Instance.allPlayerScripts[j].currentlyHeldObjectServer.scrapValue > 150)
				{
					array[j] += 30;
				}
			}
			__instance.hauntingPlayer = StartOfRound.Instance.allPlayerScripts[RoundManager.Instance.GetRandomWeightedIndex(array, ReflectionUtils.GetFieldValue<Random>(__instance, "ghostGirlRandom"))];
			if (__instance.hauntingPlayer.isPlayerDead)
			{
				for (int k = 0; k < StartOfRound.Instance.allPlayerScripts.Length; k++)
				{
					if (!StartOfRound.Instance.allPlayerScripts[k].isPlayerDead)
					{
						__instance.hauntingPlayer = StartOfRound.Instance.allPlayerScripts[k];
						break;
					}
				}
			}
			Debug.Log((object)$"Little girl: Haunting player with playerClientId: {__instance.hauntingPlayer.playerClientId}; actualClientId: {__instance.hauntingPlayer.actualClientId}");
			((EnemyAI)__instance).ChangeOwnershipOfEnemy(__instance.hauntingPlayer.actualClientId);
			__instance.hauntingLocalPlayer = (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)__instance.hauntingPlayer;
			if (ReflectionUtils.GetFieldValue<Coroutine>(__instance, "switchHauntedPlayerCoroutine") != null)
			{
				((MonoBehaviour)__instance).StopCoroutine(ReflectionUtils.GetFieldValue<Coroutine>(__instance, "switchHauntedPlayerCoroutine"));
			}
			ReflectionUtils.SetFieldValue(__instance, "switchHauntedPlayerCoroutine", ((MonoBehaviour)__instance).StartCoroutine(ReflectionUtils.InvokeMethod<IEnumerator>(__instance, "setSwitchingHauntingPlayer", null)));
			return false;
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddChatMessage")]
	public static class HudChatPatch
	{
		public static void Prefix(HUDManager __instance, ref string chatMessage, string nameOfUserWhoTyped = "")
		{
			if (!(__instance.lastChatMessage == chatMessage))
			{
				StringBuilder stringBuilder = new StringBuilder(chatMessage);
				for (int i = 0; i < MainClass.newPlayerCount; i++)
				{
					string oldValue = $"[playerNum{i}]";
					string playerUsername = StartOfRound.Instance.allPlayerScripts[i].playerUsername;
					stringBuilder.Replace(oldValue, playerUsername);
				}
				chatMessage = stringBuilder.ToString();
			}
		}
	}
	[HarmonyPatch(typeof(MenuManager), "Awake")]
	public static class MenuManagerLogoOverridePatch
	{
		public static void Postfix(MenuManager __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject gameObject = ((Component)((Component)__instance).transform.parent).gameObject;
				GameObject gameObject2 = ((Component)gameObject.transform.Find("MenuContainer").Find("MainButtons").Find("HeaderImage")).gameObject;
				Image component = gameObject2.GetComponent<Image>();
				MainClass.ReadSettingsFromFile();
				component.sprite = Sprite.Create(MainClass.mainLogo, new Rect(0f, 0f, (float)((Texture)MainClass.mainLogo).width, (float)((Texture)MainClass.mainLogo).height), new Vector2(0.5f, 0.5f));
				CosmeticRegistry.SpawnCosmeticGUI();
				Transform val = gameObject.transform.Find("MenuContainer").Find("LobbyHostSettings").Find("Panel")
					.Find("LobbyHostOptions")
					.Find("OptionsNormal");
				GameObject val2 = Object.Instantiate<GameObject>(MainClass.crewCountUI, val);
				RectTransform component2 = val2.GetComponent<RectTransform>();
				((Transform)component2).localPosition = new Vector3(96.9f, -70f, -6.7f);
				TMP_InputField inputField = ((Component)val2.transform.Find("InputField (TMP)")).GetComponent<TMP_InputField>();
				inputField.characterLimit = 3;
				inputField.text = MainClass.newPlayerCount.ToString();
				((UnityEvent<string>)(object)inputField.onValueChanged).AddListener((UnityAction<string>)delegate(string s)
				{
					if (int.TryParse(s, out var result))
					{
						MainClass.newPlayerCount = result;
						MainClass.newPlayerCount = Mathf.Clamp(MainClass.newPlayerCount, 1, MainClass.maxPlayerCount);
						inputField.text = MainClass.newPlayerCount.ToString();
						MainClass.SaveSettingsToFile();
					}
					else if (s.Length != 0)
					{
						inputField.text = MainClass.newPlayerCount.ToString();
						inputField.caretPosition = 1;
					}
				});
			}
			catch (Exception)
			{
			}
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "AddUserToPlayerList")]
	public static class AddUserPlayerListPatch
	{
		public static bool Prefix(QuickMenuManager __instance, ulong steamId, string playerName, int playerObjectId)
		{
			QuickmenuVisualInjectPatch.PopulateQuickMenu(__instance);
			MainClass.EnablePlayerObjectsBasedOnConnected();
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "RemoveUserFromPlayerList")]
	public static class RemoveUserPlayerListPatch
	{
		public static bool Prefix(QuickMenuManager __instance)
		{
			QuickmenuVisualInjectPatch.PopulateQuickMenu(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "Update")]
	public static class QuickMenuUpdatePatch
	{
		public static bool Prefix(QuickMenuManager __instance)
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "NonHostPlayerSlotsEnabled")]
	public static class QuickMenuDisplayPatch
	{
		public static bool Prefix(QuickMenuManager __instance, ref bool __result)
		{
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "Start")]
	public static class QuickmenuVisualInjectPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__2_2;

			internal void <PopulateQuickMenu>b__2_2()
			{
				if (!GameNetworkManager.Instance.disableSteam)
				{
				}
			}
		}

		public static GameObject quickMenuScrollInstance;

		public static void Postfix(QuickMenuManager __instance)
		{
			//IL_0050: 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)
			GameObject gameObject = ((Component)__instance.playerListPanel.transform.Find("Image")).gameObject;
			GameObject val = Object.Instantiate<GameObject>(MainClass.quickMenuScrollParent);
			val.transform.SetParent(gameObject.transform);
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).localPosition = new Vector3(0f, -31.2f, 0f);
			((Transform)component).localScale = Vector3.one;
			quickMenuScrollInstance = val;
		}

		public static void PopulateQuickMenu(QuickMenuManager __instance)
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			int childCount = quickMenuScrollInstance.transform.Find("Holder").childCount;
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < childCount; i++)
			{
				list.Add(((Component)quickMenuScrollInstance.transform.Find("Holder").GetChild(i)).gameObject);
			}
			foreach (GameObject item in list)
			{
				Object.Destroy((Object)(object)item);
			}
			if (!Object.op_Implicit((Object)(object)StartOfRound.Instance))
			{
				return;
			}
			for (int j = 0; j < StartOfRound.Instance.allPlayerScripts.Length; j++)
			{
				PlayerControllerB playerScript = StartOfRound.Instance.allPlayerScripts[j];
				if (!playerScript.isPlayerControlled && !playerScript.isPlayerDead)
				{
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(MainClass.playerEntry, quickMenuScrollInstance.transform.Find("Holder"));
				RectTransform component = val.GetComponent<RectTransform>();
				((Transform)component).localScale = Vector3.one;
				((Transform)component).localPosition = new Vector3(0f, 0f - ((Transform)component).localPosition.y, 0f);
				TextMeshProUGUI component2 = ((Component)val.transform.Find("PlayerNameButton").Find("PName")).GetComponent<TextMeshProUGUI>();
				((TMP_Text)component2).text = playerScript.playerUsername;
				Slider playerVolume = ((Component)val.transform.Find("PlayerVolumeSlider")).GetComponent<Slider>();
				int finalIndex = j;
				((UnityEvent<float>)(object)playerVolume.onValueChanged).AddListener((UnityAction<float>)delegate(float f)
				{
					if (playerScript.isPlayerControlled || playerScript.isPlayerDead)
					{
						float num = f / playerVolume.maxValue + 1f;
						if (num <= -1f)
						{
							SoundManager.Instance.playerVoiceVolumes[finalIndex] = -70f;
						}
						else
						{
							SoundManager.Instance.playerVoiceVolumes[finalIndex] = num;
						}
					}
				});
				if (StartOfRound.Instance.localPlayerController.playerClientId == playerScript.playerClientId)
				{
					((Component)playerVolume).gameObject.SetActive(false);
					((Component)val.transform.Find("Text (1)")).gameObject.SetActive(false);
				}
				Button component3 = ((Component)val.transform.Find("KickButton")).GetComponent<Button>();
				((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
				{
					__instance.KickUserFromServer(finalIndex);
				});
				if (!GameNetworkManager.Instance.isHostingGame)
				{
					((Component)component3).gameObject.SetActive(false);
				}
				Button component4 = ((Component)val.transform.Find("ProfileIcon")).GetComponent<Button>();
				ButtonClickedEvent onClick = component4.onClick;
				object obj = <>c.<>9__2_2;
				if (obj == null)
				{
					UnityAction val2 = delegate
					{
						if (!GameNetworkManager.Instance.disableSteam)
						{
						}
					};
					<>c.<>9__2_2 = val2;
					obj = (object)val2;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "UpdateBoxesSpectateUI")]
	public static class SpectatorBoxUpdatePatch
	{
		public static void Postfix(HUDManager __instance)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Animator, PlayerControllerB> fieldValue = ReflectionUtils.GetFieldValue<Dictionary<Animator, PlayerControllerB>>(__instance, "spectatingPlayerBoxes");
			int num = -64;
			int num2 = 0;
			int num3 = 0;
			int num4 = -70;
			int num5 = 230;
			int num6 = 4;
			foreach (KeyValuePair<Animator, PlayerControllerB> item in fieldValue)
			{
				if (((Component)item.Key).gameObject.activeInHierarchy)
				{
					GameObject gameObject = ((Component)item.Key).gameObject;
					RectTransform component = gameObject.GetComponent<RectTransform>();
					int num7 = (int)Math.Floor((double)num3 / (double)num6);
					int num8 = num3 % num6;
					int num9 = num8 * num4;
					int num10 = num7 * num5;
					component.anchoredPosition = Vector2.op_Implicit(new Vector3((float)(num + num10), (float)(num2 + num9), 0f));
					num3++;
				}
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "FillEndGameStats")]
	public static class HudFillEndGameFix
	{
		public static bool Prefix(HUDManager __instance, EndOfGameStats stats)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Invalid comparison between Unknown and I4
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < __instance.statsUIElements.playerNamesText.Length; i++)
			{
				PlayerControllerB val = __instance.playersManager.allPlayerScripts[i];
				((TMP_Text)__instance.statsUIElements.playerNamesText[i]).text = "";
				((Behaviour)__instance.statsUIElements.playerStates[i]).enabled = false;
				((TMP_Text)__instance.statsUIElements.playerNotesText[i]).text = "Notes: \n";
				if (val.disconnectedMidGame || val.isPlayerDead || val.isPlayerControlled)
				{
					if (val.isPlayerDead)
					{
						num++;
					}
					else if (val.isPlayerControlled)
					{
						num2++;
					}
					((TMP_Text)__instance.statsUIElements.playerNamesText[i]).text = __instance.playersManager.allPlayerScripts[i].playerUsername;
					((Behaviour)__instance.statsUIElements.playerStates[i]).enabled = true;
					if (__instance.playersManager.allPlayerScripts[i].isPlayerDead)
					{
						if ((int)__instance.playersManager.allPlayerScripts[i].causeOfDeath == 10)
						{
							__instance.statsUIElements.playerStates[i].sprite = __instance.statsUIElements.missingIcon;
						}
						else
						{
							__instance.statsUIElements.playerStates[i].sprite = __instance.statsUIElements.deceasedIcon;
						}
					}
					else
					{
						__instance.statsUIElements.playerStates[i].sprite = __instance.statsUIElements.aliveIcon;
					}
					for (int j = 0; j < 3 && j < stats.allPlayerStats[i].playerNotes.Count; j++)
					{
						TextMeshProUGUI val2 = __instance.statsUIElements.playerNotesText[i];
						((TMP_Text)val2).text = ((TMP_Text)val2).text + "* " + stats.allPlayerStats[i].playerNotes[j] + "\n";
					}
				}
				else
				{
					((TMP_Text)__instance.statsUIElements.playerNotesText[i]).text = "";
				}
			}
			((TMP_Text)__instance.statsUIElements.quotaNumerator).text = RoundManager.Instance.scrapCollectedInLevel.ToString();
			((TMP_Text)__instance.statsUIElements.quotaDenominator).text = RoundManager.Instance.totalScrapValueInLevel.ToString();
			if (StartOfRound.Instance.allPlayersDead)
			{
				((Behaviour)__instance.statsUIElements.allPlayersDeadOverlay).enabled = true;
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "F";
				return false;
			}
			((Behaviour)__instance.statsUIElements.allPlayersDeadOverlay).enabled = false;
			int num3 = 0;
			float num4 = (float)RoundManager.Instance.scrapCollectedInLevel / RoundManager.Instance.totalScrapValueInLevel;
			if (num2 == StartOfRound.Instance.connectedPlayersAmount + 1)
			{
				num3++;
			}
			else if (num > 1)
			{
				num3--;
			}
			if (num4 >= 0.99f)
			{
				num3 += 2;
			}
			else if (num4 >= 0.6f)
			{
				num3++;
			}
			else if (num4 <= 0.25f)
			{
				num3--;
			}
			switch (num3)
			{
			case -1:
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "D";
				return false;
			case 0:
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "C";
				return false;
			case 1:
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "B";
				return false;
			case 2:
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "A";
				return false;
			case 3:
				((TMP_Text)__instance.statsUIElements.gradeLetter).text = "S";
				return false;
			default:
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Start")]
	public static class HudStartPatch
	{
		public static void Postfix(HUDManager __instance)
		{
			//IL_0082: 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)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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)
			EndOfGameStatUIElements statsUIElements = __instance.statsUIElements;
			GameObject gameObject = ((Component)((Component)statsUIElements.playerNamesText[0]).gameObject.transform.parent).gameObject;
			GameObject gameObject2 = ((Component)gameObject.transform.parent.parent).gameObject;
			GameObject gameObject3 = ((Component)gameObject2.transform.Find("BGBoxes")).gameObject;
			gameObject2.transform.parent.Find("DeathScreen").SetSiblingIndex(3);
			gameObject3.transform.localScale = new Vector3(2.5f, 1f, 1f);
			MakePlayerHolder(4, gameObject, statsUIElements, new Vector3(426.9556f, -0.7932f, 0f));
			MakePlayerHolder(5, gameObject, statsUIElements, new Vector3(426.9556f, -115.4483f, 0f));
			MakePlayerHolder(6, gameObject, statsUIElements, new Vector3(-253.6783f, -115.4483f, 0f));
			MakePlayerHolder(7, gameObject, statsUIElements, new Vector3(-253.6783f, -0.7932f, 0f));
			for (int i = 8; i < MainClass.newPlayerCount; i++)
			{
				MakePlayerHolder(i, gameObject, statsUIElements, new Vector3(10000f, 10000f, 0f));
			}
		}

		public static void MakePlayerHolder(int index, GameObject original, EndOfGameStatUIElements uiElements, Vector3 localPosition)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			if (index + 1 <= MainClass.newPlayerCount)
			{
				GameObject val = Object.Instantiate<GameObject>(original);
				RectTransform component = val.GetComponent<RectTransform>();
				RectTransform component2 = original.GetComponent<RectTransform>();
				((Transform)component).SetParent(((Transform)component2).parent);
				((Transform)component).localScale = new Vector3(1f, 1f, 1f);
				((Transform)component).localPosition = localPosition;
				GameObject gameObject = ((Component)val.transform.Find("PlayerName1")).gameObject;
				GameObject gameObject2 = ((Component)val.transform.Find("Notes")).gameObject;
				((Transform)gameObject2.GetComponent<RectTransform>()).localPosition = new Vector3(-95.7222f, 43.3303f, 0f);
				GameObject gameObject3 = ((Component)val.transform.Find("Symbol")).gameObject;
				if (index >= uiElements.playerNamesText.Length)
				{
					Array.Resize(ref uiElements.playerNamesText, index + 1);
					Array.Resize(ref uiElements.playerStates, index + 1);
					Array.Resize(ref uiElements.playerNotesText, index + 1);
				}
				uiElements.playerNamesText[index] = gameObject.GetComponent<TextMeshProUGUI>();
				uiElements.playerNotesText[index] = gameObject2.GetComponent<TextMeshProUGUI>();
				uiElements.playerStates[index] = gameObject3.GetComponent<Image>();
			}
		}
	}
	public static class PluginInformation
	{
		public const string PLUGIN_NAME = "MoreCompany";

		public const string PLUGIN_VERSION = "1.7.2";

		public const string PLUGIN_GUID = "me.swipez.melonloader.morecompany";
	}
	[BepInPlugin("me.swipez.melonloader.morecompany", "MoreCompany", "1.7.2")]
	public class MainClass : BaseUnityPlugin
	{
		public static int newPlayerCount = 32;

		public static int maxPlayerCount = 50;

		public static bool showCosmetics = true;

		public static List<PlayerControllerB> notSupposedToExistPlayers = new List<PlayerControllerB>();

		public static Texture2D mainLogo;

		public static GameObject quickMenuScrollParent;

		public static GameObject playerEntry;

		public static GameObject crewCountUI;

		public static GameObject cosmeticGUIInstance;

		public static GameObject cosmeticButton;

		public static ManualLogSource StaticLogger;

		public static Dictionary<int, List<string>> playerIdsAndCosmetics = new Dictionary<int, List<string>>();

		public static string cosmeticSavePath = Application.persistentDataPath + "/morecompanycosmetics.txt";

		public static string moreCompanySave = Application.persistentDataPath + "/morecompanysave.txt";

		public static string dynamicCosmeticsPath = Paths.PluginPath + "/MoreCompanyCosmetics";

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			Harmony val = new Harmony("me.swipez.melonloader.morecompany");
			try
			{
				val.PatchAll();
			}
			catch (Exception ex)
			{
				StaticLogger.LogError((object)("Failed to patch: " + ex));
			}
			ManualHarmonyPatches.ManualPatch(val);
			StaticLogger.LogInfo((object)"Loading MoreCompany...");
			StaticLogger.LogInfo((object)("Checking: " + dynamicCosmeticsPath));
			if (!Directory.Exists(dynamicCosmeticsPath))
			{
				StaticLogger.LogInfo((object)"Creating cosmetics directory");
				Directory.CreateDirectory(dynamicCosmeticsPath);
			}
			ReadSettingsFromFile();
			ReadCosmeticsFromFile();
			StaticLogger.LogInfo((object)"Read settings and cosmetics");
			AssetBundle bundle = BundleUtilities.LoadBundleFromInternalAssembly("morecompany.assets", Assembly.GetExecutingAssembly());
			AssetBundle val2 = BundleUtilities.LoadBundleFromInternalAssembly("morecompany.cosmetics", Assembly.GetExecutingAssembly());
			CosmeticRegistry.LoadCosmeticsFromBundle(val2);
			val2.Unload(false);
			SteamFriends.OnGameLobbyJoinRequested += delegate(Lobby lobby, SteamId steamId)
			{
				newPlayerCount = ((Lobby)(ref lobby)).MaxMembers;
			};
			SteamMatchmaking.OnLobbyEntered += delegate(Lobby lobby)
			{
				newPlayerCount = ((Lobby)(ref lobby)).MaxMembers;
			};
			StaticLogger.LogInfo((object)"Loading USER COSMETICS...");
			RecursiveCosmeticLoad(Paths.PluginPath);
			LoadAssets(bundle);
			StaticLogger.LogInfo((object)"Loaded MoreCompany FULLY");
		}

		private void RecursiveCosmeticLoad(string directory)
		{
			string[] directories = Directory.GetDirectories(directory);
			foreach (string directory2 in directories)
			{
				RecursiveCosmeticLoad(directory2);
			}
			string[] files = Directory.GetFiles(directory);
			foreach (string text in files)
			{
				if (text.EndsWith(".cosmetics"))
				{
					AssetBundle val = AssetBundle.LoadFromFile(text);
					CosmeticRegistry.LoadCosmeticsFromBundle(val);
					val.Unload(false);
				}
			}
		}

		private void ReadCosmeticsFromFile()
		{
			if (File.Exists(cosmeticSavePath))
			{
				string[] array = File.ReadAllLines(cosmeticSavePath);
				string[] array2 = array;
				foreach (string item in array2)
				{
					CosmeticRegistry.locallySelectedCosmetics.Add(item);
				}
			}
		}

		public static void WriteCosmeticsToFile()
		{
			string text = "";
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				text = text + locallySelectedCosmetic + "\n";
			}
			File.WriteAllText(cosmeticSavePath, text);
		}

		public static void SaveSettingsToFile()
		{
			string text = "";
			text = text + newPlayerCount + "\n";
			text = text + showCosmetics + "\n";
			File.WriteAllText(moreCompanySave, text);
		}

		public static void ReadSettingsFromFile()
		{
			if (File.Exists(moreCompanySave))
			{
				string[] array = File.ReadAllLines(moreCompanySave);
				try
				{
					newPlayerCount = int.Parse(array[0]);
					showCosmetics = bool.Parse(array[1]);
				}
				catch (Exception)
				{
					StaticLogger.LogError((object)"Failed to read settings from file, resetting to default");
					newPlayerCount = 32;
					showCosmetics = true;
				}
			}
		}

		private static void LoadAssets(AssetBundle bundle)
		{
			if (Object.op_Implicit((Object)(object)bundle))
			{
				mainLogo = bundle.LoadPersistentAsset<Texture2D>("assets/morecompanyassets/morecompanytransparentred.png");
				quickMenuScrollParent = bundle.LoadPersistentAsset<GameObject>("assets/morecompanyassets/quickmenuoverride.prefab");
				playerEntry = bundle.LoadPersistentAsset<GameObject>("assets/morecompanyassets/playerlistslot.prefab");
				cosmeticGUIInstance = bundle.LoadPersistentAsset<GameObject>("assets/morecompanyassets/testoverlay.prefab");
				cosmeticButton = bundle.LoadPersistentAsset<GameObject>("assets/morecompanyassets/cosmeticinstance.prefab");
				crewCountUI = bundle.LoadPersistentAsset<GameObject>("assets/morecompanyassets/crewcountfield.prefab");
				bundle.Unload(false);
			}
		}

		public static void ResizePlayerCache(Dictionary<uint, Dictionary<int, NetworkObject>> ScenePlacedObjects)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			StartOfRound instance = StartOfRound.Instance;
			if (instance.allPlayerObjects.Length == newPlayerCount)
			{
				return;
			}
			playerIdsAndCosmetics.Clear();
			uint num = 10000u;
			int num2 = newPlayerCount - instance.allPlayerObjects.Length;
			int num3 = instance.allPlayerObjects.Length;
			GameObject val = instance.allPlayerObjects[3];
			for (int i = 0; i < num2; i++)
			{
				uint num4 = num + (uint)i;
				GameObject val2 = Object.Instantiate<GameObject>(val);
				NetworkObject component = val2.GetComponent<NetworkObject>();
				ReflectionUtils.SetFieldValue(component, "GlobalObjectIdHash", num4);
				Scene scene = ((Component)component).gameObject.scene;
				int handle = ((Scene)(ref scene)).handle;
				uint num5 = num4;
				if (!ScenePlacedObjects.ContainsKey(num5))
				{
					ScenePlacedObjects.Add(num5, new Dictionary<int, NetworkObject>());
				}
				if (ScenePlacedObjects[num5].ContainsKey(handle))
				{
					string arg = (((Object)(object)ScenePlacedObjects[num5][handle] != (Object)null) ? ((Object)ScenePlacedObjects[num5][handle]).name : "Null Entry");
					throw new Exception(((Object)component).name + " tried to registered with ScenePlacedObjects which already contains " + string.Format("the same {0} value {1} for {2}!", "GlobalObjectIdHash", num5, arg));
				}
				ScenePlacedObjects[num5].Add(handle, component);
				((Object)val2).name = $"Player ({4 + i})";
				val2.transform.parent = null;
				PlayerControllerB componentInChildren = val2.GetComponentInChildren<PlayerControllerB>();
				notSupposedToExistPlayers.Add(componentInChildren);
				componentInChildren.playerClientId = (ulong)(4 + i);
				componentInChildren.isPlayerControlled = false;
				componentInChildren.isPlayerDead = false;
				componentInChildren.DropAllHeldItems(false, false);
				componentInChildren.TeleportPlayer(instance.notSpawnedPosition.position, false, 0f, false, true);
				UnlockableSuit.SwitchSuitForPlayer(componentInChildren, 0, false);
				Array.Resize(ref instance.allPlayerObjects, instance.allPlayerObjects.Length + 1);
				Array.Resize(ref instance.allPlayerScripts, instance.allPlayerScripts.Length + 1);
				Array.Resize(ref instance.gameStats.allPlayerStats, instance.gameStats.allPlayerStats.Length + 1);
				Array.Resize(ref instance.playerSpawnPositions, instance.playerSpawnPositions.Length + 1);
				instance.allPlayerObjects[num3 + i] = val2;
				instance.gameStats.allPlayerStats[num3 + i] = new PlayerStats();
				instance.allPlayerScripts[num3 + i] = componentInChildren;
				instance.playerSpawnPositions[num3 + i] = instance.playerSpawnPositions[3];
			}
		}

		public static void EnablePlayerObjectsBasedOnConnected()
		{
			int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				for (int j = 0; j < connectedPlayersAmount + 1; j++)
				{
					if (!val.isPlayerControlled)
					{
						((Component)val).gameObject.SetActive(false);
					}
					else
					{
						((Component)val).gameObject.SetActive(true);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SendNewPlayerValuesServerRpc")]
	public static class SendNewPlayerValuesServerRpcPatch
	{
		public static ulong lastId;

		public static void Prefix(PlayerControllerB __instance, ulong newPlayerSteamId)
		{
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening && networkManager.IsServer)
			{
				lastId = newPlayerSteamId;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SendNewPlayerValuesClientRpc")]
	public static class SendNewPlayerValuesClientRpcPatch
	{
		public static void Prefix(PlayerControllerB __instance, ref ulong[] playerSteamIds)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return;
			}
			if (StartOfRound.Instance.mapScreen.radarTargets.Count != MainClass.newPlayerCount)
			{
				List<PlayerControllerB> useless = new List<PlayerControllerB>();
				foreach (PlayerControllerB notSupposedToExistPlayer in MainClass.notSupposedToExistPlayers)
				{
					if (Object.op_Implicit((Object)(object)notSupposedToExistPlayer))
					{
						StartOfRound.Instance.mapScreen.radarTargets.Add(new TransformAndName(((Component)notSupposedToExistPlayer).transform, notSupposedToExistPlayer.playerUsername, false));
					}
					else
					{
						useless.Add(notSupposedToExistPlayer);
					}
				}
				MainClass.notSupposedToExistPlayers.RemoveAll((PlayerControllerB x) => useless.Contains(x));
			}
			if (!networkManager.IsServer)
			{
				return;
			}
			List<ulong> list = new List<ulong>();
			for (int i = 0; i < MainClass.newPlayerCount; i++)
			{
				if (i == (int)__instance.playerClientId)
				{
					list.Add(SendNewPlayerValuesServerRpcPatch.lastId);
				}
				else
				{
					list.Add(__instance.playersManager.allPlayerScripts[i].playerSteamId);
				}
			}
			playerSteamIds = list.ToArray();
		}
	}
	public static class HUDManagerBullshitPatch
	{
		public static bool ManualPrefix(HUDManager __instance)
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")]
	public static class SyncShipUnlockablePatch
	{
		public static void Prefix(StartOfRound __instance, ref int[] playerSuitIDs, bool shipLightsOn, Vector3[] placeableObjectPositions, Vector3[] placeableObjectRotations, int[] placeableObjects, int[] storedItems, int[] scrapValues, int[] itemSaveData)
		{
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening && networkManager.IsServer)
			{
				int[] array = new int[MainClass.newPlayerCount];
				for (int i = 0; i < MainClass.newPlayerCount; i++)
				{
					array[i] = __instance.allPlayerScripts[i].currentSuitID;
				}
				playerSuitIDs = array;
			}
		}
	}
	[HarmonyPatch(typeof(NetworkSceneManager), "PopulateScenePlacedObjects")]
	public static class ScenePlacedObjectsInitPatch
	{
		public static void Postfix(ref Dictionary<uint, Dictionary<int, NetworkObject>> ___ScenePlacedObjects)
		{
			MainClass.ResizePlayerCache(___ScenePlacedObjects);
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")]
	public static class LobbyDataJoinablePatch
	{
		public static bool Prefix(ref bool __result)
		{
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkConnectionManager), "HandleConnectionApproval")]
	public static class ConnectionApprovalTest
	{
		public static void Prefix(ulong ownerClientId, ConnectionApprovalResponse response)
		{
			if (Object.op_Implicit((Object)(object)StartOfRound.Instance))
			{
				if (StartOfRound.Instance.connectedPlayersAmount >= MainClass.newPlayerCount)
				{
					response.Approved = false;
					response.Reason = "Server is full";
				}
				else
				{
					response.Approved = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SteamMatchmaking), "CreateLobbyAsync")]
	public static class LobbyThingPatch
	{
		public static void Prefix(ref int maxMembers)
		{
			MainClass.ReadSettingsFromFile();
			maxMembers = MainClass.newPlayerCount;
		}
	}
	public class ManualHarmonyPatches
	{
		public static void ManualPatch(Harmony HarmonyInstance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			HarmonyInstance.Patch((MethodBase)AccessTools.Method(typeof(HUDManager), "SyncAllPlayerLevelsServerRpc", new Type[0], (Type[])null), new HarmonyMethod(typeof(HUDManagerBullshitPatch).GetMethod("ManualPrefix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	public class MimicPatches
	{
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "SetEnemyOutside")]
		public class MaskedPlayerEnemyOnEnablePatch
		{
			public static void Postfix(MaskedPlayerEnemy __instance)
			{
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance.mimickingPlayer != (Object)null))
				{
					return;
				}
				List<string> list = MainClass.playerIdsAndCosmetics[(int)__instance.mimickingPlayer.playerClientId];
				Transform val = ((Component)__instance).transform.Find("ScavengerModel").Find("metarig");
				CosmeticApplication component = ((Component)val).GetComponent<CosmeticApplication>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.ClearCosmetics();
					Object.Destroy((Object)(object)component);
				}
				component = ((Component)val).gameObject.AddComponent<CosmeticApplication>();
				foreach (string item in list)
				{
					component.ApplyCosmetic(item, startEnabled: true);
				}
				foreach (CosmeticInstance spawnedCosmetic in component.spawnedCosmetics)
				{
					Transform transform = ((Component)spawnedCosmetic).transform;
					transform.localScale *= 0.38f;
				}
			}
		}
	}
	public class ReflectionUtils
	{
		public static void InvokeMethod(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void InvokeMethod(object obj, Type forceType, string methodName, object[] parameters)
		{
			MethodInfo method = forceType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void SetPropertyValue(object obj, string propertyName, object value)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			property.SetValue(obj, value);
		}

		public static T InvokeMethod<T>(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)method.Invoke(obj, parameters);
		}

		public static T GetFieldValue<T>(object obj, string fieldName)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)field.GetValue(obj);
		}

		public static void SetFieldValue(object obj, string fieldName, object value)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			field.SetValue(obj, value);
		}
	}
	[HarmonyPatch(typeof(ShipTeleporter), "Awake")]
	public static class ShipTeleporterAwakePatch
	{
		public static void Postfix(ShipTeleporter __instance)
		{
			int[] array = new int[MainClass.newPlayerCount];
			for (int i = 0; i < MainClass.newPlayerCount; i++)
			{
				array[i] = -1;
			}
			ReflectionUtils.SetFieldValue(__instance, "playersBeingTeleported", array);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpectateNextPlayer")]
	public static class SpectatePatches
	{
		public static bool Prefix(PlayerControllerB __instance)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			if ((Object)(object)__instance.spectatedPlayerScript != (Object)null)
			{
				num = (int)__instance.spectatedPlayerScript.playerClientId;
			}
			for (int i = 0; i < MainClass.newPlayerCount; i++)
			{
				num = (num + 1) % MainClass.newPlayerCount;
				if (!__instance.playersManager.allPlayerScripts[num].isPlayerDead && __instance.playersManager.allPlayerScripts[num].isPlayerControlled && (Object)(object)__instance.playersManager.allPlayerScripts[num] != (Object)(object)__instance)
				{
					__instance.spectatedPlayerScript = __instance.playersManager.allPlayerScripts[num];
					__instance.SetSpectatedPlayerEffects(false);
					return false;
				}
			}
			if ((Object)(object)__instance.deadBody != (Object)null && ((Component)__instance.deadBody).gameObject.activeSelf)
			{
				__instance.spectateCameraPivot.position = __instance.deadBody.bodyParts[0].position;
				ReflectionUtils.InvokeMethod(__instance, "RaycastSpectateCameraAroundPivot", null);
			}
			StartOfRound.Instance.SetPlayerSafeInShip();
			return false;
		}
	}
	[HarmonyPatch(typeof(SoundManager), "Start")]
	public static class SoundManagerStartPatch
	{
		public static void Postfix()
		{
			int num = MainClass.newPlayerCount - 4;
			int num2 = 4;
			for (int i = 0; i < num; i++)
			{
				Array.Resize(ref SoundManager.Instance.playerVoicePitches, SoundManager.Instance.playerVoicePitches.Length + 1);
				Array.Resize(ref SoundManager.Instance.playerVoicePitchTargets, SoundManager.Instance.playerVoicePitchTargets.Length + 1);
				Array.Resize(ref SoundManager.Instance.playerVoiceVolumes, SoundManager.Instance.playerVoiceVolumes.Length + 1);
				Array.Resize(ref SoundManager.Instance.playerVoicePitchLerpSpeed, SoundManager.Instance.playerVoicePitchLerpSpeed.Length + 1);
				Array.Resize(ref SoundManager.Instance.playerVoiceMixers, SoundManager.Instance.playerVoiceMixers.Length + 1);
				AudioMixerGroup val = ((IEnumerable<AudioMixerGroup>)Resources.FindObjectsOfTypeAll<AudioMixerGroup>()).FirstOrDefault((Func<AudioMixerGroup, bool>)((AudioMixerGroup x) => ((Object)x).name.Contains("Voice")));
				SoundManager.Instance.playerVoicePitches[num2 + i] = 1f;
				SoundManager.Instance.playerVoicePitchTargets[num2 + i] = 1f;
				SoundManager.Instance.playerVoiceVolumes[num2 + i] = 0.5f;
				SoundManager.Instance.playerVoicePitchLerpSpeed[num2 + i] = 3f;
				SoundManager.Instance.playerVoiceMixers[num2 + i] = val;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "GetPlayerSpawnPosition")]
	public static class SpawnPositionClampPatch
	{
		public static void Prefix(ref int playerNum, bool simpleTeleport = false)
		{
			if (playerNum > 3)
			{
				playerNum = 3;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnClientConnect")]
	public static class OnClientConnectedPatch
	{
		public static bool Prefix(StartOfRound __instance, ulong clientId)
		{
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return false;
			}
			Debug.Log((object)"player connected");
			Debug.Log((object)$"connected players #: {__instance.connectedPlayersAmount}");
			try
			{
				List<int> list = __instance.ClientPlayerList.Values.ToList();
				Debug.Log((object)$"Connecting new player on host; clientId: {clientId}");
				int num = 0;
				for (int i = 1; i < MainClass.newPlayerCount; i++)
				{
					if (!list.Contains(i))
					{
						num = i;
						break;
					}
				}
				__instance.allPlayerScripts[num].actualClientId = clientId;
				__instance.allPlayerObjects[num].GetComponent<NetworkObject>().ChangeOwnership(clientId);
				Debug.Log((object)$"New player assigned object id: {__instance.allPlayerObjects[num]}");
				List<ulong> list2 = new List<ulong>();
				for (int j = 0; j < __instance.allPlayerObjects.Length; j++)
				{
					NetworkObject component = __instance.allPlayerObjects[j].GetComponent<NetworkObject>();
					if (!component.IsOwnedByServer)
					{
						list2.Add(component.OwnerClientId);
					}
					else if (j == 0)
					{
						list2.Add(NetworkManager.Singleton.LocalClientId);
					}
					else
					{
						list2.Add(999uL);
					}
				}
				int groupCredits = Object.FindObjectOfType<Terminal>().groupCredits;
				int profitQuota = TimeOfDay.Instance.profitQuota;
				int quotaFulfilled = TimeOfDay.Instance.quotaFulfilled;
				int num2 = (int)TimeOfDay.Instance.timeUntilDeadline;
				ReflectionUtils.InvokeMethod(__instance, "OnPlayerConnectedClientRpc", new object[10]
				{
					clientId,
					__instance.connectedPlayersAmount,
					list2.ToArray(),
					num,
					groupCredits,
					__instance.currentLevelID,
					profitQuota,
					num2,
					quotaFulfilled,
					__instance.randomMapSeed
				});
				__instance.ClientPlayerList.Add(clientId, num);
				Debug.Log((object)$"client id connecting: {clientId} ; their corresponding player object id: {num}");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"Error occured in OnClientConnected! Shutting server down. clientId: {clientId}. Error: {arg}");
				GameNetworkManager.Instance.disconnectionReasonMessage = "Error occured when a player attempted to join the server! Restart the application and please report the glitch!";
				GameNetworkManager.Instance.Disconnect();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(SteamLobbyManager), "LoadServerList")]
	public static class LoadServerListPatch
	{
		public static bool Prefix(SteamLobbyManager __instance)
		{
			OverrideMethod(__instance);
			return false;
		}

		private static async void OverrideMethod(SteamLobbyManager __instance)
		{
			if (GameNetworkManager.Instance.waitingForLobbyDataRefresh)
			{
				return;
			}
			ReflectionUtils.SetFieldValue(__instance, "refreshServerListTimer", 0f);
			((TMP_Text)__instance.serverListBlankText).text = "Loading server list...";
			ReflectionUtils.GetFieldValue<Lobby[]>(__instance, "currentLobbyList");
			LobbySlot[] array = Object.FindObjectsOfType<LobbySlot>();
			for (int i = 0; i < array.Length; i++)
			{
				Object.Destroy((Object)(object)((Component)array[i]).gameObject);
			}
			LobbyQuery val;
			switch (__instance.sortByDistanceSetting)
			{
			case 0:
				val = SteamMatchmaking.LobbyList;
				((LobbyQuery)(ref val)).FilterDistanceClose();
				break;
			case 1:
				val = SteamMatchmaking.LobbyList;
				((LobbyQuery)(ref val)).FilterDistanceFar();
				break;
			case 2:
				val = SteamMatchmaking.LobbyList;
				((LobbyQuery)(ref val)).FilterDistanceWorldwide();
				break;
			}
			Debug.Log((object)"Requested server list");
			GameNetworkManager.Instance.waitingForLobbyDataRefresh = true;
			Lobby[] currentLobbyList;
			switch (__instance.sortByDistanceSetting)
			{
			case 0:
				val = SteamMatchmaking.LobbyList;
				val = ((LobbyQuery)(ref val)).FilterDistanceClose();
				val = ((LobbyQuery)(ref val)).WithSlotsAvailable(1);
				val = ((LobbyQuery)(ref val)).WithKeyValue("vers", GameNetworkManager.Instance.gameVersionNum.ToString());
				currentLobbyList = await ((LobbyQuery)(ref val)).RequestAsync();
				break;
			case 1:
				val = SteamMatchmaking.LobbyList;
				val = ((LobbyQuery)(ref val)).FilterDistanceFar();
				val = ((LobbyQuery)(ref val)).WithSlotsAvailable(1);
				val = ((LobbyQuery)(ref val)).WithKeyValue("vers", GameNetworkManager.Instance.gameVersionNum.ToString());
				currentLobbyList = await ((LobbyQuery)(ref val)).RequestAsync();
				break;
			default:
				val = SteamMatchmaking.LobbyList;
				val = ((LobbyQuery)(ref val)).FilterDistanceWorldwide();
				val = ((LobbyQuery)(ref val)).WithSlotsAvailable(1);
				val = ((LobbyQuery)(ref val)).WithKeyValue("vers", GameNetworkManager.Instance.gameVersionNum.ToString());
				currentLobbyList = await ((LobbyQuery)(ref val)).RequestAsync();
				break;
			}
			GameNetworkManager.Instance.waitingForLobbyDataRefresh = false;
			if (currentLobbyList != null)
			{
				Debug.Log((object)"Got lobby list!");
				ReflectionUtils.InvokeMethod(__instance, "DebugLogServerList", null);
				if (currentLobbyList.Length == 0)
				{
					((TMP_Text)__instance.serverListBlankText).text = "No available servers to join.";
				}
				else
				{
					((TMP_Text)__instance.serverListBlankText).text = "";
				}
				ReflectionUtils.SetFieldValue(__instance, "lobbySlotPositionOffset", 0f);
				for (int j = 0; j < currentLobbyList.Length; j++)
				{
					Friend[] array2 = SteamFriends.GetBlocked().ToArray();
					if (array2 != null)
					{
						for (int k = 0; k < array2.Length; k++)
						{
							Debug.Log((object)$"blocked user: {((Friend)(ref array2[k])).Name}; id: {array2[k].Id}");
							if (((Lobby)(ref currentLobbyList[j])).IsOwnedBy(array2[k].Id))
							{
								Debug.Log((object)("Hiding lobby by blocked user: " + ((Friend)(ref array2[k])).Name));
							}
						}
					}
					else
					{
						Debug.Log((object)"Blocked users list is null");
					}
					GameObject gameObject = Object.Instantiate<GameObject>(__instance.LobbySlotPrefab, __instance.levelListContainer);
					gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0f + ReflectionUtils.GetFieldValue<float>(__instance, "lobbySlotPositionOffset"));
					ReflectionUtils.SetFieldValue(__instance, "lobbySlotPositionOffset", ReflectionUtils.GetFieldValue<float>(__instance, "lobbySlotPositionOffset") - 42f);
					LobbySlot componentInChildren = gameObject.GetComponentInChildren<LobbySlot>();
					((TMP_Text)componentInChildren.LobbyName).text = ((Lobby)(ref currentLobbyList[j])).GetData("name");
					((TMP_Text)componentInChildren.playerCount).text = $"{((Lobby)(ref currentLobbyList[j])).MemberCount} / {((Lobby)(ref currentLobbyList[j])).MaxMembers}";
					componentInChildren.lobbyId = ((Lobby)(ref currentLobbyList[j])).Id;
					componentInChildren.thisLobby = currentLobbyList[j];
					ReflectionUtils.SetFieldValue(__instance, "currentLobbyList", currentLobbyList);
				}
			}
			else
			{
				Debug.Log((object)"Lobby list is null after request.");
				((TMP_Text)__instance.serverListBlankText).text = "No available servers to join.";
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "Awake")]
	public static class GameNetworkAwakePatch
	{
		public static int originalVersion;

		public static void Postfix(GameNetworkManager __instance)
		{
			originalVersion = __instance.gameVersionNum;
			if (!AssemblyChecker.HasAssemblyLoaded("lc_api"))
			{
				__instance.gameVersionNum = 9999;
			}
		}
	}
	[HarmonyPatch(typeof(MenuManager), "Awake")]
	public static class MenuManagerVersionDisplayPatch
	{
		public static void Postfix(MenuManager __instance)
		{
			if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)__instance.versionNumberText != (Object)null)
			{
				((TMP_Text)__instance.versionNumberText).text = $"v{GameNetworkAwakePatch.originalVersion} (MC)";
			}
		}
	}
}
namespace MoreCompany.Utils
{
	public class AssemblyChecker
	{
		public static bool HasAssemblyLoaded(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				if (assembly.GetName().Name.ToLower().Equals(name))
				{
					return true;
				}
			}
			return false;
		}
	}
	public class BundleUtilities
	{
		public static byte[] GetResourceBytes(string filename, Assembly assembly)
		{
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.Contains(filename))
				{
					continue;
				}
				using Stream stream = assembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					return null;
				}
				byte[] array = new byte[stream.Length];
				stream.Read(array, 0, array.Length);
				return array;
			}
			return null;
		}

		public static AssetBundle LoadBundleFromInternalAssembly(string filename, Assembly assembly)
		{
			return AssetBundle.LoadFromMemory(GetResourceBytes(filename, assembly));
		}
	}
	public static class AssetBundleExtension
	{
		public static T LoadPersistentAsset<T>(this AssetBundle bundle, string name) where T : Object
		{
			Object val = bundle.LoadAsset(name);
			if (val != (Object)null)
			{
				val.hideFlags = (HideFlags)32;
				return (T)(object)val;
			}
			return default(T);
		}
	}
}
namespace MoreCompany.Cosmetics
{
	public class CosmeticApplication : MonoBehaviour
	{
		public Transform head;

		public Transform hip;

		public Transform lowerArmRight;

		public Transform shinLeft;

		public Transform shinRight;

		public Transform chest;

		public List<CosmeticInstance> spawnedCosmetics = new List<CosmeticInstance>();

		public void Awake()
		{
			head = ((Component)this).transform.Find("spine").Find("spine.001").Find("spine.002")
				.Find("spine.003")
				.Find("spine.004");
			chest = ((Component)this).transform.Find("spine").Find("spine.001").Find("spine.002")
				.Find("spine.003");
			lowerArmRight = ((Component)this).transform.Find("spine").Find("spine.001").Find("spine.002")
				.Find("spine.003")
				.Find("shoulder.R")
				.Find("arm.R_upper")
				.Find("arm.R_lower");
			hip = ((Component)this).transform.Find("spine");
			shinLeft = ((Component)this).transform.Find("spine").Find("thigh.L").Find("shin.L");
			shinRight = ((Component)this).transform.Find("spine").Find("thigh.R").Find("shin.R");
			RefreshAllCosmeticPositions();
		}

		private void OnDisable()
		{
			foreach (CosmeticInstance spawnedCosmetic in spawnedCosmetics)
			{
				((Component)spawnedCosmetic).gameObject.SetActive(false);
			}
		}

		private void OnEnable()
		{
			foreach (CosmeticInstance spawnedCosmetic in spawnedCosmetics)
			{
				((Component)spawnedCosmetic).gameObject.SetActive(true);
			}
		}

		public void ClearCosmetics()
		{
			foreach (CosmeticInstance spawnedCosmetic in spawnedCosmetics)
			{
				Object.Destroy((Object)(object)((Component)spawnedCosmetic).gameObject);
			}
			spawnedCosmetics.Clear();
		}

		public void ApplyCosmetic(string cosmeticId, bool startEnabled)
		{
			if (CosmeticRegistry.cosmeticInstances.ContainsKey(cosmeticId))
			{
				CosmeticInstance cosmeticInstance = CosmeticRegistry.cosmeticInstances[cosmeticId];
				GameObject val = Object.Instantiate<GameObject>(((Component)cosmeticInstance).gameObject);
				val.SetActive(startEnabled);
				CosmeticInstance component = val.GetComponent<CosmeticInstance>();
				spawnedCosmetics.Add(component);
				if (startEnabled)
				{
					ParentCosmetic(component);
				}
			}
		}

		public void RefreshAllCosmeticPositions()
		{
			foreach (CosmeticInstance spawnedCosmetic in spawnedCosmetics)
			{
				ParentCosmetic(spawnedCosmetic);
			}
		}

		private void ParentCosmetic(CosmeticInstance cosmeticInstance)
		{
			//IL_006d: 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)
			Transform val = null;
			switch (cosmeticInstance.cosmeticType)
			{
			case CosmeticType.HAT:
				val = head;
				break;
			case CosmeticType.R_LOWER_ARM:
				val = lowerArmRight;
				break;
			case CosmeticType.HIP:
				val = hip;
				break;
			case CosmeticType.L_SHIN:
				val = shinLeft;
				break;
			case CosmeticType.R_SHIN:
				val = shinRight;
				break;
			case CosmeticType.CHEST:
				val = chest;
				break;
			}
			((Component)cosmeticInstance).transform.position = val.position;
			((Component)cosmeticInstance).transform.rotation = val.rotation;
			((Component)cosmeticInstance).transform.parent = val;
		}
	}
	public class CosmeticInstance : MonoBehaviour
	{
		public CosmeticType cosmeticType;

		public string cosmeticId;

		public Texture2D icon;
	}
	public class CosmeticGeneric
	{
		public virtual string gameObjectPath { get; }

		public virtual string cosmeticId { get; }

		public virtual string textureIconPath { get; }

		public CosmeticType cosmeticType { get; }

		public void LoadFromBundle(AssetBundle bundle)
		{
			GameObject val = bundle.LoadPersistentAsset<GameObject>(gameObjectPath);
			Texture2D icon = bundle.LoadPersistentAsset<Texture2D>(textureIconPath);
			CosmeticInstance cosmeticInstance = val.AddComponent<CosmeticInstance>();
			cosmeticInstance.cosmeticId = cosmeticId;
			cosmeticInstance.icon = icon;
			cosmeticInstance.cosmeticType = cosmeticType;
			MainClass.StaticLogger.LogInfo((object)("Loaded cosmetic: " + cosmeticId + " from bundle: " + ((Object)bundle).name));
			CosmeticRegistry.cosmeticInstances.Add(cosmeticId, cosmeticInstance);
		}
	}
	public enum CosmeticType
	{
		HAT,
		WRIST,
		CHEST,
		R_LOWER_ARM,
		HIP,
		L_SHIN,
		R_SHIN
	}
	public class CosmeticRegistry
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__8_0;

			public static UnityAction <>9__8_1;

			internal void <SpawnCosmeticGUI>b__8_0()
			{
				MainClass.showCosmetics = true;
				MainClass.SaveSettingsToFile();
			}

			internal void <SpawnCosmeticGUI>b__8_1()
			{
				MainClass.showCosmetics = false;
				MainClass.SaveSettingsToFile();
			}
		}

		public static Dictionary<string, CosmeticInstance> cosmeticInstances = new Dictionary<string, CosmeticInstance>();

		public static GameObject cosmeticGUI;

		private static GameObject displayGuy;

		private static CosmeticApplication cosmeticApplication;

		public static List<string> locallySelectedCosmetics = new List<string>();

		public const float COSMETIC_PLAYER_SCALE_MULT = 0.38f;

		public static void LoadCosmeticsFromBundle(AssetBundle bundle)
		{
			string[] allAssetNames = bundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				if (text.EndsWith(".prefab"))
				{
					GameObject val = bundle.LoadPersistentAsset<GameObject>(text);
					CosmeticInstance component = val.GetComponent<CosmeticInstance>();
					if (!((Object)(object)component == (Object)null))
					{
						MainClass.StaticLogger.LogInfo((object)("Loaded cosmetic: " + component.cosmeticId + " from bundle"));
						cosmeticInstances.Add(component.cosmeticId, component);
					}
				}
			}
		}

		public static void LoadCosmeticsFromAssembly(Assembly assembly, AssetBundle bundle)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.IsSubclassOf(typeof(CosmeticGeneric)))
				{
					CosmeticGeneric cosmeticGeneric = (CosmeticGeneric)type.GetConstructor(new Type[0]).Invoke(new object[0]);
					cosmeticGeneric.LoadFromBundle(bundle);
				}
			}
		}

		public static void SpawnCosmeticGUI()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			cosmeticGUI = Object.Instantiate<GameObject>(MainClass.cosmeticGUIInstance);
			((Component)cosmeticGUI.transform.Find("Canvas").Find("GlobalScale")).transform.localScale = new Vector3(2f, 2f, 2f);
			displayGuy = ((Component)cosmeticGUI.transform.Find("Canvas").Find("GlobalScale").Find("CosmeticsScreen")
				.Find("ObjectHolder")
				.Find("ScavengerModel")
				.Find("metarig")).gameObject;
			cosmeticApplication = displayGuy.AddComponent<CosmeticApplication>();
			GameObject gameObject = ((Component)cosmeticGUI.transform.Find("Canvas").Find("GlobalScale").Find("CosmeticsScreen")
				.Find("EnableButton")).gameObject;
			ButtonClickedEvent onClick = gameObject.GetComponent<Button>().onClick;
			object obj = <>c.<>9__8_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					MainClass.showCosmetics = true;
					MainClass.SaveSettingsToFile();
				};
				<>c.<>9__8_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			GameObject gameObject2 = ((Component)cosmeticGUI.transform.Find("Canvas").Find("GlobalScale").Find("CosmeticsScreen")
				.Find("DisableButton")).gameObject;
			ButtonClickedEvent onClick2 = gameObject2.GetComponent<Button>().onClick;
			object obj2 = <>c.<>9__8_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					MainClass.showCosmetics = false;
					MainClass.SaveSettingsToFile();
				};
				<>c.<>9__8_1 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			if (MainClass.showCosmetics)
			{
				gameObject.SetActive(false);
				gameObject2.SetActive(true);
			}
			else
			{
				gameObject.SetActive(true);
				gameObject2.SetActive(false);
			}
			PopulateCosmetics();
			UpdateCosmeticsOnDisplayGuy(startEnabled: false);
		}

		public static void PopulateCosmetics()
		{
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			GameObject gameObject = ((Component)cosmeticGUI.transform.Find("Canvas").Find("GlobalScale").Find("CosmeticsScreen")
				.Find("CosmeticsHolder")
				.Find("Content")).gameObject;
			List<Transform> list = new List<Transform>();
			for (int i = 0; i < gameObject.transform.childCount; i++)
			{
				list.Add(gameObject.transform.GetChild(i));
			}
			foreach (Transform item in list)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (KeyValuePair<string, CosmeticInstance> cosmeticInstance in cosmeticInstances)
			{
				GameObject val = Object.Instantiate<GameObject>(MainClass.cosmeticButton, gameObject.transform);
				val.transform.localScale = Vector3.one;
				GameObject disabledOverlay = ((Component)val.transform.Find("Deselected")).gameObject;
				disabledOverlay.SetActive(true);
				GameObject enabledOverlay = ((Component)val.transform.Find("Selected")).gameObject;
				enabledOverlay.SetActive(true);
				if (IsEquipped(cosmeticInstance.Value.cosmeticId))
				{
					enabledOverlay.SetActive(true);
					disabledOverlay.SetActive(false);
				}
				else
				{
					enabledOverlay.SetActive(false);
					disabledOverlay.SetActive(true);
				}
				RawImage component = ((Component)val.transform.Find("Icon")).GetComponent<RawImage>();
				component.texture = (Texture)(object)cosmeticInstance.Value.icon;
				Button component2 = val.GetComponent<Button>();
				((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
				{
					ToggleCosmetic(cosmeticInstance.Value.cosmeticId);
					if (IsEquipped(cosmeticInstance.Value.cosmeticId))
					{
						enabledOverlay.SetActive(true);
						disabledOverlay.SetActive(false);
					}
					else
					{
						enabledOverlay.SetActive(false);
						disabledOverlay.SetActive(true);
					}
					MainClass.WriteCosmeticsToFile();
					UpdateCosmeticsOnDisplayGuy(startEnabled: true);
				});
			}
		}

		private static Color HexToColor(string hex)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString(hex, ref result);
			return result;
		}

		public static void UpdateCosmeticsOnDisplayGuy(bool startEnabled)
		{
			cosmeticApplication.ClearCosmetics();
			foreach (string locallySelectedCosmetic in locallySelectedCosmetics)
			{
				cosmeticApplication.ApplyCosmetic(locallySelectedCosmetic, startEnabled);
			}
			foreach (CosmeticInstance spawnedCosmetic in cosmeticApplication.spawnedCosmetics)
			{
				RecursiveLayerChange(((Component)spawnedCosmetic).transform, 5);
			}
		}

		private static void RecursiveLayerChange(Transform transform, int layer)
		{
			((Component)transform).gameObject.layer = layer;
			for (int i = 0; i < transform.childCount; i++)
			{
				RecursiveLayerChange(transform.GetChild(i), layer);
			}
		}

		public static bool IsEquipped(string cosmeticId)
		{
			return locallySelectedCosmetics.Contains(cosmeticId);
		}

		public static void ToggleCosmetic(string cosmeticId)
		{
			if (locallySelectedCosmetics.Contains(cosmeticId))
			{
				locallySelectedCosmetics.Remove(cosmeticId);
			}
			else
			{
				locallySelectedCosmetics.Add(cosmeticId);
			}
		}
	}
}
namespace MoreCompany.Behaviors
{
	public class SpinDragger : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler
	{
		public float speed = 1f;

		private Vector2 lastMousePosition;

		private bool dragging = false;

		private Vector3 rotationalVelocity = Vector3.zero;

		public float dragSpeed = 1f;

		public float airDrag = 0.99f;

		public GameObject target;

		private void Update()
		{
			//IL_0076: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_001c: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (dragging)
			{
				Vector3 val = Vector2.op_Implicit(((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue() - lastMousePosition);
				rotationalVelocity += new Vector3(0f, 0f - val.x, 0f) * dragSpeed;
				lastMousePosition = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			}
			rotationalVelocity *= airDrag;
			target.transform.Rotate(rotationalVelocity * Time.deltaTime * speed, (Space)0);
		}

		public void OnPointerDown(PointerEventData eventData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			lastMousePosition = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			dragging = true;
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			dragging = false;
		}
	}
}

BepInEx/plugins/FreddyBracken.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FreddyBracken")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FreddyBracken")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2ed810b2-476e-4150-b015-645ee4681b3d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FreddyBracken
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "FreddyBracken";

		public const string PLUGIN_NAME = "FreddyBracken";

		public const string PLUGIN_VERSION = "1.0.4";
	}
	[BepInPlugin("FreddyBracken", "FreddyBracken", "1.0.4")]
	public class Plugin : BaseUnityPlugin
	{
		public static GameObject Visuals;

		public static AudioClip NeckCrackAudio;

		public static AudioClip AngeredAudio;

		public static Texture2D FreddyMaterial;

		public static Texture2D FreddyNormal;

		public static Texture2D FreddyEyes;

		public static ConfigEntry<bool> useFreddyTextures;

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin FreddyBracken is loaded!");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "freddy.bundle");
			AssetBundle val = AssetBundle.LoadFromFile(text);
			Visuals = val.LoadAsset<GameObject>("assets/prefabs/freddy.prefab");
			NeckCrackAudio = val.LoadAsset<AudioClip>("assets/prefabs/freddycrackneck.wav");
			AngeredAudio = val.LoadAsset<AudioClip>("assets/prefabs/freddyangered.wav");
			FreddyMaterial = val.LoadAsset<Texture2D>("assets/prefabs/freddy_albedo.png");
			FreddyNormal = val.LoadAsset<Texture2D>("assets/prefabs/freddy_normal.png");
			FreddyEyes = val.LoadAsset<Texture2D>("assets/prefabs/freddy_eyes_albedo.png");
			useFreddyTextures = ((BaseUnityPlugin)this).Config.Bind<bool>("FreddyBracken", "UseFreddyTextures", false, "Swap out the default dark Bracken body material for Freddy's actual brown fur, bowtie, etc materials.");
			SkinnedMeshRenderer[] componentsInChildren = Visuals.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				((Component)val2).gameObject.layer = LayerMask.NameToLayer("Enemies");
			}
		}
	}
}
namespace FreddyBracken.Patches
{
	[HarmonyPatch(typeof(FlowermanAI), "Start")]
	internal class FlowermanPatch
	{
		private static void Postfix(FlowermanAI __instance)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			if ((Object)(object)Plugin.Visuals == (Object)null)
			{
				return;
			}
			Transform val = ((Component)__instance).transform.Find("FlowermanModel");
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				Transform obj2 = val.Find("LOD1");
				obj = ((obj2 != null) ? ((Component)obj2).GetComponent<SkinnedMeshRenderer>() : null);
			}
			SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)obj;
			object obj3;
			if (val == null)
			{
				obj3 = null;
			}
			else
			{
				Transform obj4 = val.Find("AnimContainer");
				obj3 = ((obj4 != null) ? obj4.Find("metarig") : null);
			}
			Transform val3 = (Transform)obj3;
			if (!((Object)(object)val2 == (Object)null) && ((Renderer)val2).enabled)
			{
				((Renderer)val2).enabled = false;
				Renderer[] componentsInChildren = ((Component)val3).gameObject.GetComponentsInChildren<Renderer>();
				foreach (Renderer val4 in componentsInChildren)
				{
					val4.enabled = false;
				}
				GameObject val5 = Object.Instantiate<GameObject>(Plugin.Visuals);
				val5.transform.SetParent(val);
				val5.transform.localPosition = Vector3.zero;
				val5.transform.localRotation = Quaternion.identity;
				val5.transform.localScale = Vector3.one;
				Transform val6 = val5.transform.Find("Container/Body_Geo");
				Transform val7 = val5.transform.Find("Container/metarig");
				val7.SetParent(val3.parent, true);
				((Component)val7).transform.localScale = ((Component)val3).transform.localScale;
				((Component)val7).transform.localRotation = ((Component)val3).transform.localRotation;
				((Component)val7).transform.localPosition = ((Component)val3).transform.localPosition;
				SkinnedMeshRenderer component = ((Component)val6).GetComponent<SkinnedMeshRenderer>();
				component.rootBone = val7;
				if (Plugin.useFreddyTextures.Value)
				{
					MaterialPropertyBlock val8 = new MaterialPropertyBlock();
					((Renderer)component).GetPropertyBlock(val8, 0);
					val8.SetColor("_BaseColor", Color.white);
					val8.SetColor("_Color", Color.white);
					val8.SetTexture("_BaseColorMap", (Texture)(object)Plugin.FreddyMaterial);
					val8.SetVector("_BaseColorMap_ST", new Vector4(1f, 1f, 0f, 0f));
					val8.SetFloat("_NormalMapSpace", 0f);
					val8.SetTexture("_NormalMap", (Texture)(object)Plugin.FreddyNormal);
					val8.SetVector("_NormalMap_ST", new Vector4(1f, 1f, 0f, 0f));
					val8.SetFloat("_Metallic", 0f);
					((Renderer)component).SetPropertyBlock(val8, 0);
					MaterialPropertyBlock val9 = new MaterialPropertyBlock();
					((Renderer)component).GetPropertyBlock(val9, 1);
					val8.SetTexture("_BaseColorMap", (Texture)(object)Plugin.FreddyEyes);
					((Renderer)component).SetPropertyBlock(val9, 1);
				}
				((Object)val3).name = "old-metarig";
				__instance.crackNeckSFX = Plugin.NeckCrackAudio;
				__instance.creatureAngerVoice.clip = Plugin.AngeredAudio;
				__instance.rightHandGrip = val7.Find("Torso1").Find("Torso2").Find("Torso3")
					.Find("Arm1.R")
					.Find("Arm2.R")
					.Find("Arm3.R")
					.Find("Hand1.R")
					.Find("HandGripPosition");
			}
		}
	}
}

BepInEx/plugins/MoreEmotes1.1.1.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using MoreEmotes.Patch;
using Tools;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FuckYouMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FuckYouMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5ecc2bf2-af12-4e83-a6f1-cf2eacbf3060")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tools
{
	public class Reflection
	{
		public static object GetInstanceField(Type type, object instance, string fieldName)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(fieldName, bindingAttr);
			return field.GetValue(instance);
		}

		public static object CallMethod(object instance, string methodName, params object[] args)
		{
			MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				return method.Invoke(instance, args);
			}
			return null;
		}
	}
}
namespace MoreEmotes
{
	[BepInPlugin("MoreEmotes", "MoreEmotes-Sligili", "1.1.1")]
	public class FuckYouModInitialization : BaseUnityPlugin
	{
		private Harmony _harmony;

		private ConfigEntry<string> config_KeyEmote3;

		private ConfigEntry<string> config_KeyEmote4;

		private ConfigEntry<string> config_KeyEmote5;

		private ConfigEntry<string> config_KeyEmote6;

		private ConfigEntry<bool> config_toggleEmote3;

		private ConfigEntry<bool> config_toggleEmote4;

		private ConfigEntry<bool> config_toggleEmote5;

		private ConfigEntry<bool> config_toggleEmote6;

		private void Awake()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreEmotes loaded");
			EmotePatch.animationsBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animationsbundle"));
			EmotePatch.animatorBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animatorbundle"));
			EmotePatch.local = EmotePatch.animatorBundle.LoadAsset<RuntimeAnimatorController>("Assets/MoreEmotes/NEWmetarig.controller");
			EmotePatch.others = EmotePatch.animatorBundle.LoadAsset<RuntimeAnimatorController>("Assets/MoreEmotes/NEWmetarigOtherPlayers.controller");
			ConfigFile();
			_harmony = new Harmony("MoreEmotes");
			_harmony.PatchAll(typeof(EmotePatch));
		}

		private void ConfigFile()
		{
			config_KeyEmote3 = ((BaseUnityPlugin)this).Config.Bind<string>("MIDDLEFINGER", "EmoteKey", "3", "SUPPORTED KEYS A-Z | 0-9 | F1-F12 ");
			config_toggleEmote3 = ((BaseUnityPlugin)this).Config.Bind<bool>("MIDDLEFINGER", "Enable", true, "TOGGLE MIDDLEFINGER EMOTE KEY");
			EmotePatch.keyBind_Emote3 = config_KeyEmote3.Value;
			EmotePatch.enable3 = config_toggleEmote3.Value;
			config_KeyEmote4 = ((BaseUnityPlugin)this).Config.Bind<string>("THE GRIDDY", "EmoteKey", "6", "SUPPORTED KEYS A-Z | 0-9 | F1-F12 ");
			config_toggleEmote4 = ((BaseUnityPlugin)this).Config.Bind<bool>("THE GRIDDY", "Enable", true, "TOGGLE THE GRIDDY EMOTE KEY");
			EmotePatch.keyBind_Emote4 = config_KeyEmote4.Value;
			EmotePatch.enable4 = config_toggleEmote4.Value;
			config_KeyEmote5 = ((BaseUnityPlugin)this).Config.Bind<string>("SHY", "EmoteKey", "5", "SUPPORTED KEYS A-Z | 0-9 | F1-F12 ");
			config_toggleEmote5 = ((BaseUnityPlugin)this).Config.Bind<bool>("SHY", "Enable", true, "TOGGLE SHY EMOTE KEY");
			EmotePatch.keyBind_Emote5 = config_KeyEmote5.Value;
			EmotePatch.enable5 = config_toggleEmote5.Value;
			config_KeyEmote6 = ((BaseUnityPlugin)this).Config.Bind<string>("CLAP", "EmoteKey", "4", "SUPPORTED KEYS A-Z | 0-9 | F1-F12 ");
			config_toggleEmote6 = ((BaseUnityPlugin)this).Config.Bind<bool>("CLAP", "Enable", true, "TOGGLE CLAP EMOTE KEY");
			EmotePatch.keyBind_Emote6 = config_KeyEmote6.Value;
			EmotePatch.enable6 = config_toggleEmote6.Value;
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "MoreEmotes";

		public const string Name = "MoreEmotes-Sligili";

		public const string Ver = "1.1.1";
	}
}
namespace MoreEmotes.Patch
{
	internal class EmotePatch
	{
		public static AssetBundle animationsBundle;

		public static AssetBundle animatorBundle;

		private static bool keyFlag_Emote3;

		public static bool enable3;

		private static bool keyFlag_Emote4;

		public static bool enable4;

		private static bool keyFlag_Emote5;

		public static bool enable5;

		private static bool keyFlag_Emote6;

		public static bool enable6;

		public static string keyBind_Emote3;

		public static string keyBind_Emote4;

		public static string keyBind_Emote5;

		public static string keyBind_Emote6;

		private static CallbackContext context;

		public static RuntimeAnimatorController local;

		public static RuntimeAnimatorController others;

		private static AudioClip _clap1;

		private static AudioClip _clap2;

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(PlayerControllerB __instance)
		{
			GameObject gameObject = ((Component)((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel")).transform.Find("metarig")).gameObject;
			CustomAudioAnimationEvent customAudioAnimationEvent = gameObject.AddComponent<CustomAudioAnimationEvent>();
			customAudioAnimationEvent.player = __instance;
			if ((Object)(object)_clap1 == (Object)null)
			{
				_clap1 = animationsBundle.LoadAsset<AudioClip>("Assets/MoreEmotes/SingleClapEmote1.wav");
			}
			if ((Object)(object)_clap2 == (Object)null)
			{
				_clap2 = animationsBundle.LoadAsset<AudioClip>("Assets/MoreEmotes/SingleClapEmote2.wav");
			}
			customAudioAnimationEvent.clap1 = _clap1;
			customAudioAnimationEvent.clap2 = _clap2;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void UpdatePrefix(PlayerControllerB __instance)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.isPlayerControlled || !((NetworkBehaviour)__instance).IsOwner)
			{
				__instance.playerBodyAnimator.runtimeAnimatorController = others;
				return;
			}
			if ((Object)(object)__instance.playerBodyAnimator != (Object)(object)local)
			{
				__instance.playerBodyAnimator.runtimeAnimatorController = local;
			}
			if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote3], 0f) && !keyFlag_Emote3 && enable3)
			{
				keyFlag_Emote3 = true;
				__instance.PerformEmote(context, 3);
			}
			else if (!InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote3], 0f))
			{
				keyFlag_Emote3 = false;
			}
			if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote4], 0f) && !keyFlag_Emote4 && enable4 && !__instance.isHoldingObject)
			{
				keyFlag_Emote4 = true;
				__instance.PerformEmote(context, 4);
			}
			else if (!InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote4], 0f))
			{
				keyFlag_Emote4 = false;
			}
			if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote5], 0f) && !keyFlag_Emote5 && enable5 && !__instance.isHoldingObject)
			{
				keyFlag_Emote5 = true;
				__instance.PerformEmote(context, 5);
			}
			else if (!InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote5], 0f))
			{
				keyFlag_Emote5 = false;
			}
			if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote6], 0f) && !keyFlag_Emote6 && enable6 && !__instance.isHoldingObject)
			{
				keyFlag_Emote6 = true;
				__instance.PerformEmote(context, 6);
			}
			else if (!InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind_Emote6], 0f))
			{
				keyFlag_Emote6 = false;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PerformEmote")]
		[HarmonyPrefix]
		private static void PerformEmotePrefix(CallbackContext context, int emoteID, PlayerControllerB __instance)
		{
			if ((emoteID >= 3 || ((CallbackContext)(ref context)).performed) && ((((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject)) || __instance.isTestingPlayer) && (bool)Reflection.CallMethod(__instance, "CheckConditionsForEmote") && !(__instance.timeSinceStartingEmote < 0.5f))
			{
				__instance.timeSinceStartingEmote = 0f;
				__instance.performingEmote = true;
				__instance.playerBodyAnimator.SetInteger("emoteNumber", emoteID);
				__instance.StartPerformingEmoteServerRpc();
			}
		}
	}
	public class CustomAudioAnimationEvent : MonoBehaviour
	{
		private Animator animator;

		private AudioSource SoundsSource;

		public AudioClip clap1;

		public AudioClip clap2;

		public AudioClip clap3;

		public PlayerControllerB player;

		private void Start()
		{
			animator = ((Component)this).GetComponent<Animator>();
			SoundsSource = player.movementAudio;
		}

		public void PlayClapSound()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || animator.GetInteger("emoteNumber") == 6))
			{
				bool flag = player.isInHangarShipRoom && player.playersManager.hangarDoorsClosed;
				RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 22f, 0.6f, 0, flag, 6);
				SoundsSource.pitch = Random.Range(0.59f, 0.79f);
				switch (Random.Range(0, 2))
				{
				case 0:
					SoundsSource.PlayOneShot(clap1);
					break;
				case 1:
					SoundsSource.PlayOneShot(clap2);
					break;
				}
			}
		}

		public void PlayFootstepSound()
		{
			if (player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || animator.GetInteger("emoteNumber") == 4))
			{
				player.PlayFootstepLocal();
				player.PlayFootstepServer();
			}
		}
	}
}

BepInEx/plugins/HelmetCamera.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("HelmetCamera")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HelmetCamera")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b99c4d46-5f13-47b3-a5af-5e3f37772e77")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HelmetCamera
{
	[BepInPlugin("RickArg.lethalcompany.helmetcameras", "Helmet_Cameras", "2.1.4")]
	public class PluginInit : BaseUnityPlugin
	{
		public static Harmony _harmony;

		public static ConfigEntry<int> config_isHighQuality;

		public static ConfigEntry<int> config_renderDistance;

		public static ConfigEntry<int> config_cameraFps;

		private void Awake()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			config_isHighQuality = ((BaseUnityPlugin)this).Config.Bind<int>("MONITOR QUALITY", "monitorResolution", 0, "Low FPS affection. High Quality mode. 0 - vanilla (48x48), 1 - vanilla+ (128x128), 2 - mid quality (256x256), 3 - high quality (512x512), 4 - Very High Quality (1024x1024)");
			config_renderDistance = ((BaseUnityPlugin)this).Config.Bind<int>("MONITOR QUALITY", "renderDistance", 20, "Low FPS affection. Render distance for helmet camera.");
			config_cameraFps = ((BaseUnityPlugin)this).Config.Bind<int>("MONITOR QUALITY", "cameraFps", 30, "Very high FPS affection. FPS for helmet camera. To increase YOUR fps, you should low cameraFps value.");
			_harmony = new Harmony("HelmetCamera");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Helmet_Cameras is loaded with version 2.1.4!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"--------Helmet camera patch done.---------");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "RickArg.lethalcompany.helmetcameras";

		public const string PLUGIN_NAME = "Helmet_Cameras";

		public const string PLUGIN_VERSION = "2.1.4";
	}
	public class Plugin : MonoBehaviour
	{
		private RenderTexture renderTexture;

		private bool isMonitorChanged = false;

		private GameObject helmetCameraNew;

		private bool isSceneLoaded = false;

		private bool isCoroutineStarted = false;

		private int currentTransformIndex;

		private int resolution = 0;

		private int renderDistance = 50;

		private float cameraFps = 30f;

		private float elapsed;

		private void Awake()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			resolution = PluginInit.config_isHighQuality.Value;
			renderDistance = PluginInit.config_renderDistance.Value;
			cameraFps = PluginInit.config_cameraFps.Value;
			switch (resolution)
			{
			case 0:
				renderTexture = new RenderTexture(48, 48, 24);
				break;
			case 1:
				renderTexture = new RenderTexture(128, 128, 24);
				break;
			case 2:
				renderTexture = new RenderTexture(256, 256, 24);
				break;
			case 3:
				renderTexture = new RenderTexture(512, 512, 24);
				break;
			case 4:
				renderTexture = new RenderTexture(1024, 1024, 24);
				break;
			}
		}

		public void Start()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			isCoroutineStarted = false;
			while ((Object)(object)helmetCameraNew == (Object)null)
			{
				helmetCameraNew = new GameObject("HelmetCamera");
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "MainMenu")
			{
				activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name != "InitScene")
				{
					activeScene = SceneManager.GetActiveScene();
					if (((Scene)(ref activeScene)).name != "InitSceneLaunchOptions")
					{
						isSceneLoaded = true;
						Debug.Log((object)"[HELMET_CAMERAS] Starting coroutine...");
						((MonoBehaviour)this).StartCoroutine(LoadSceneEnter());
						return;
					}
				}
			}
			isSceneLoaded = false;
			isMonitorChanged = false;
		}

		private IEnumerator LoadSceneEnter()
		{
			Debug.Log((object)"[HELMET_CAMERAS] 5 seconds for init mode... Please wait...");
			yield return (object)new WaitForSeconds(5f);
			isCoroutineStarted = true;
			if ((Object)(object)GameObject.Find("Environment/HangarShip/Cameras/ShipCamera") != (Object)null)
			{
				Debug.Log((object)"[HELMET_CAMERAS] Ship camera founded...");
				if (!isMonitorChanged)
				{
					((Renderer)GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube").GetComponent<MeshRenderer>()).materials[2].mainTexture = ((Renderer)GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001").GetComponent<MeshRenderer>()).materials[2].mainTexture;
					((Renderer)GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001").GetComponent<MeshRenderer>()).materials[2].mainTexture = (Texture)(object)renderTexture;
					helmetCameraNew.AddComponent<Camera>();
					((Behaviour)helmetCameraNew.GetComponent<Camera>()).enabled = false;
					helmetCameraNew.GetComponent<Camera>().targetTexture = renderTexture;
					helmetCameraNew.GetComponent<Camera>().cullingMask = 20649983;
					helmetCameraNew.GetComponent<Camera>().farClipPlane = renderDistance;
					helmetCameraNew.GetComponent<Camera>().nearClipPlane = 0.55f;
					isMonitorChanged = true;
					Debug.Log((object)"[HELMET_CAMERAS] Monitors were changed...");
					Debug.Log((object)"[HELMET_CAMERAS] Turning off vanilla internal ship camera");
					((Behaviour)GameObject.Find("Environment/HangarShip/Cameras/ShipCamera").GetComponent<Camera>()).enabled = false;
				}
			}
		}

		public void Update()
		{
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			bool flag = isSceneLoaded && isCoroutineStarted;
			if (flag && StartOfRound.Instance.localPlayerController.isInHangarShipRoom)
			{
				Debug.Log((object)"[HELMET_CAMERAS] Player in ship! Rendering the camera...");
				helmetCameraNew.SetActive(true);
				elapsed += Time.deltaTime;
				if (elapsed > 1f / cameraFps)
				{
					elapsed = 0f;
					((Behaviour)helmetCameraNew.GetComponent<Camera>()).enabled = true;
				}
				else
				{
					((Behaviour)helmetCameraNew.GetComponent<Camera>()).enabled = false;
				}
				GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001/CameraMonitorScript");
				currentTransformIndex = val.GetComponent<ManualCameraRenderer>().targetTransformIndex;
				TransformAndName val2 = val.GetComponent<ManualCameraRenderer>().radarTargets[currentTransformIndex];
				if (!val2.isNonPlayer)
				{
					try
					{
						helmetCameraNew.transform.SetPositionAndRotation(val2.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera/HelmetLights").position + new Vector3(0f, 0f, 0f), val2.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera/HelmetLights").rotation * Quaternion.Euler(0f, 0f, 0f));
						DeadBodyInfo[] array = Object.FindObjectsOfType<DeadBodyInfo>();
						for (int i = 0; i < array.Length; i++)
						{
							if (array[i].playerScript.playerUsername == val2.name)
							{
								helmetCameraNew.transform.SetPositionAndRotation(((Component)array[i]).gameObject.transform.Find("spine.001/spine.002/spine.003").position, ((Component)array[i]).gameObject.transform.Find("spine.001/spine.002/spine.003").rotation * Quaternion.Euler(0f, 0f, 0f));
							}
						}
						return;
					}
					catch (NullReferenceException)
					{
						Debug.Log((object)"[HELMET_CAMERAS] ERROR NULL REFERENCE");
						return;
					}
				}
				helmetCameraNew.transform.SetPositionAndRotation(val2.transform.position + new Vector3(0f, 1.6f, 0f), val2.transform.rotation * Quaternion.Euler(0f, -90f, 0f));
			}
			else if (flag && !StartOfRound.Instance.localPlayerController.isInHangarShipRoom)
			{
				helmetCameraNew.SetActive(false);
			}
		}
	}
}
namespace HelmetCamera.Patches
{
	[HarmonyPatch]
	internal class HelmetCamera
	{
		public static void InitCameras()
		{
			GameObject val = GameObject.Find("Environment/HangarShip/Cameras/ShipCamera");
			val.AddComponent<Plugin>();
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		public static void InitCamera(ref ManualCameraRenderer __instance)
		{
			InitCameras();
		}
	}
}

BepInEx/plugins/ShipLobby/ShipLobby.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShipLobby")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("ShipLobby")]
[assembly: AssemblyCopyright("Copyright © tinyhoot 2023")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
namespace ShipLobby
{
	[BepInPlugin("com.github.tinyhoot.ShipLobby", "ShipLobby", "1.0.2")]
	internal class ShipLobby : BaseUnityPlugin
	{
		public const string GUID = "com.github.tinyhoot.ShipLobby";

		public const string NAME = "ShipLobby";

		public const string VERSION = "1.0.2";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.github.tinyhoot.ShipLobby").PatchAll(Assembly.GetExecutingAssembly());
		}
	}
}
namespace ShipLobby.Patches
{
	[HarmonyPatch]
	internal class GameNetworkManagerPatcher
	{
		private static QuickMenuManager _quickMenuManager;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientConnectedCallback")]
		private static void LogConnect()
		{
			ShipLobby.Log.LogDebug((object)"Player connected.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientDisconnectCallback")]
		private static void LogDisconnect()
		{
			ShipLobby.Log.LogDebug((object)"Player disconnected.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		private static void FixConnectionApproval(GameNetworkManager __instance, ConnectionApprovalResponse response)
		{
			if (!response.Approved && !(response.Reason != "Game has already started!") && __instance.gameHasStarted && StartOfRound.Instance.inShipPhase)
			{
				ShipLobby.Log.LogDebug((object)"Approving incoming late connection.");
				response.Reason = "";
				response.Approved = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")]
		private static void FixFriendInviteButton()
		{
			if (GameNetworkManager.Instance.gameHasStarted && StartOfRound.Instance.inShipPhase)
			{
				GameNetworkManager.Instance.InviteFriendsUI();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")]
		private static bool PreventSteamLobbyLeaving(GameNetworkManager __instance)
		{
			ShipLobby.Log.LogDebug((object)"Preventing the closing of Steam lobby.");
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		private static void CloseSteamLobby(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && __instance.inShipPhase)
			{
				ShipLobby.Log.LogDebug((object)"Setting lobby to not joinable.");
				GameNetworkManager.Instance.SetLobbyJoinable(false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		private static IEnumerator ReopenSteamLobby(IEnumerator coroutine, StartOfRound __instance)
		{
			while (coroutine.MoveNext())
			{
				yield return coroutine.Current;
			}
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(0.5f);
			yield return (object)new WaitUntil((Func<bool>)(() => !__instance.firingPlayersCutsceneRunning));
			ShipLobby.Log.LogDebug((object)"Reopening lobby, setting to joinable.");
			GameNetworkManager instance = GameNetworkManager.Instance;
			if (instance.currentLobby.HasValue)
			{
				instance.SetLobbyJoinable(true);
				if ((Object)(object)_quickMenuManager == (Object)null)
				{
					_quickMenuManager = Object.FindObjectOfType<QuickMenuManager>();
				}
				_quickMenuManager.inviteFriendsTextAlpha.alpha = 1f;
			}
		}
	}
}

BepInEx/patchers/BepInEx.MonoMod.HookGenPatcher/BepInEx.MonoMod.HookGenPatcher.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using BepInEx.Configuration;
using BepInEx.Logging;
using Mono.Cecil;
using MonoMod;
using MonoMod.RuntimeDetour.HookGen;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Bepinex.Monomod.HookGenPatcher")]
[assembly: AssemblyDescription("Runtime HookGen for BepInEx")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HarbingerOfMe")]
[assembly: AssemblyProduct("Bepinex.Monomod.HookGenPatcher")]
[assembly: AssemblyCopyright("HarbingerOfMe-2022")]
[assembly: AssemblyTrademark("MIT")]
[assembly: ComVisible(false)]
[assembly: Guid("12032e45-9577-4195-8f4f-a729911b2f08")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: AssemblyVersion("1.2.1.0")]
namespace BepInEx.MonoMod.HookGenPatcher;

public static class HookGenPatcher
{
	internal static ManualLogSource Logger = Logger.CreateLogSource("HookGenPatcher");

	private const string CONFIG_FILE_NAME = "HookGenPatcher.cfg";

	private static readonly ConfigFile Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "HookGenPatcher.cfg"), true);

	private const char EntrySeparator = ',';

	private static readonly ConfigEntry<string> AssemblyNamesToHookGenPatch = Config.Bind<string>("General", "MMHOOKAssemblyNames", "Assembly-CSharp.dll", $"Assembly names to make mmhooks for, separate entries with : {','} ");

	private static readonly ConfigEntry<bool> preciseHash = Config.Bind<bool>("General", "Preciser filehashing", false, "Hash file using contents instead of size. Minor perfomance impact.");

	private static bool skipHashing => !preciseHash.Value;

	public static IEnumerable<string> TargetDLLs { get; } = new string[0];


	public static void Initialize()
	{
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Expected O, but got Unknown
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Expected O, but got Unknown
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Expected O, but got Unknown
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Expected O, but got Unknown
		string[] array = AssemblyNamesToHookGenPatch.Value.Split(new char[1] { ',' });
		string text = Path.Combine(Paths.PluginPath, "MMHOOK");
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			string text3 = "MMHOOK_" + text2;
			string text4 = Path.Combine(Paths.ManagedPath, text2);
			string text5 = Path.Combine(text, text3);
			bool flag = true;
			string[] files = Directory.GetFiles(Paths.PluginPath, text3, SearchOption.AllDirectories);
			foreach (string text6 in files)
			{
				if (Path.GetFileName(text6).Equals(text3))
				{
					text5 = text6;
					Logger.LogInfo((object)"Previous MMHOOK location found. Using that location to save instead.");
					flag = false;
					break;
				}
			}
			if (flag)
			{
				Directory.CreateDirectory(text);
			}
			FileInfo fileInfo = new FileInfo(text4);
			long length = fileInfo.Length;
			long num = 0L;
			if (File.Exists(text5))
			{
				try
				{
					AssemblyDefinition val = AssemblyDefinition.ReadAssembly(text5);
					try
					{
						if (val.MainModule.GetType("BepHookGen.size" + length) != null)
						{
							if (skipHashing)
							{
								Logger.LogInfo((object)"Already ran for this version, reusing that file.");
								continue;
							}
							num = fileInfo.makeHash();
							if (val.MainModule.GetType("BepHookGen.content" + num) != null)
							{
								Logger.LogInfo((object)"Already ran for this version, reusing that file.");
								continue;
							}
						}
					}
					finally
					{
						((IDisposable)val)?.Dispose();
					}
				}
				catch (BadImageFormatException)
				{
					Logger.LogWarning((object)("Failed to read " + Path.GetFileName(text5) + ", probably corrupted, remaking one."));
				}
			}
			Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_PRIVATE", "1");
			Environment.SetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW", "0");
			MonoModder val2 = new MonoModder
			{
				InputPath = text4,
				OutputPath = text5,
				ReadingMode = (ReadingMode)2
			};
			try
			{
				IAssemblyResolver assemblyResolver = val2.AssemblyResolver;
				IAssemblyResolver obj = ((assemblyResolver is BaseAssemblyResolver) ? assemblyResolver : null);
				if (obj != null)
				{
					((BaseAssemblyResolver)obj).AddSearchDirectory(Paths.BepInExAssemblyDirectory);
				}
				val2.Read();
				val2.MapDependencies();
				if (File.Exists(text5))
				{
					Logger.LogDebug((object)("Clearing " + text5));
					File.Delete(text5);
				}
				Logger.LogInfo((object)"Starting HookGenerator");
				HookGenerator val3 = new HookGenerator(val2, Path.GetFileName(text5));
				ModuleDefinition outputModule = val3.OutputModule;
				try
				{
					val3.Generate();
					outputModule.Types.Add(new TypeDefinition("BepHookGen", "size" + length, (TypeAttributes)1, outputModule.TypeSystem.Object));
					if (!skipHashing)
					{
						outputModule.Types.Add(new TypeDefinition("BepHookGen", "content" + ((num == 0L) ? fileInfo.makeHash() : num), (TypeAttributes)1, outputModule.TypeSystem.Object));
					}
					outputModule.Write(text5);
				}
				finally
				{
					((IDisposable)outputModule)?.Dispose();
				}
				Logger.LogInfo((object)"Done.");
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}
	}

	public static void Patch(AssemblyDefinition _)
	{
	}

	private static long makeHash(this FileInfo fileInfo)
	{
		FileStream inputStream = fileInfo.OpenRead();
		byte[] value = null;
		using (MD5 mD = new MD5CryptoServiceProvider())
		{
			value = mD.ComputeHash(inputStream);
		}
		long num = BitConverter.ToInt64(value, 0);
		if (num == 0L)
		{
			return 1L;
		}
		return num;
	}
}

BepInEx/patchers/BepInEx.MonoMod.HookGenPatcher/MonoMod.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Mdb;
using Mono.Cecil.Pdb;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.InlineRT;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("0x0ade")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2021 0x0ade")]
[assembly: AssemblyDescription("General purpose .NET assembly modding \"basework\". This package contains the core IL patcher and relinker.")]
[assembly: AssemblyFileVersion("21.8.5.1")]
[assembly: AssemblyInformationalVersion("21.08.05.01")]
[assembly: AssemblyProduct("MonoMod")]
[assembly: AssemblyTitle("MonoMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("21.8.5.1")]
[module: UnverifiableCode]
internal static class MultiTargetShims
{
	private static readonly object[] _NoArgs = new object[0];

	public static TypeReference GetConstraintType(this TypeReference type)
	{
		return type;
	}
}
namespace MonoMod
{
	[MonoMod__SafeToCopy__]
	public class MonoModAdded : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModConstructor : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModCustomAttributeAttribute : Attribute
	{
		public MonoModCustomAttributeAttribute(string h)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModCustomMethodAttributeAttribute : Attribute
	{
		public MonoModCustomMethodAttributeAttribute(string h)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModEnumReplace : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModForceCall : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModForceCallvirt : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	[Obsolete("Use MonoModLinkFrom or RuntimeDetour / HookGen instead.")]
	public class MonoModHook : Attribute
	{
		public string FindableID;

		public Type Type;

		public MonoModHook(string findableID)
		{
			FindableID = findableID;
		}

		public MonoModHook(Type type)
		{
			Type = type;
			FindableID = type.FullName;
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModIfFlag : Attribute
	{
		public MonoModIfFlag(string key)
		{
		}

		public MonoModIfFlag(string key, bool fallback)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModIgnore : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	public class MonoModLinkFrom : Attribute
	{
		public string FindableID;

		public Type Type;

		public MonoModLinkFrom(string findableID)
		{
			FindableID = findableID;
		}

		public MonoModLinkFrom(Type type)
		{
			Type = type;
			FindableID = type.FullName;
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModLinkTo : Attribute
	{
		public MonoModLinkTo(string t)
		{
		}

		public MonoModLinkTo(Type t)
		{
		}

		public MonoModLinkTo(string t, string n)
		{
		}

		public MonoModLinkTo(Type t, string n)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModNoNew : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModOnPlatform : Attribute
	{
		public MonoModOnPlatform(params Platform[] p)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModOriginal : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModOriginalName : Attribute
	{
		public MonoModOriginalName(string n)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModPatch : Attribute
	{
		public MonoModPatch(string name)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	public class MonoModPublic : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModRemove : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModReplace : Attribute
	{
	}
	[MonoMod__SafeToCopy__]
	public class MonoModTargetModule : Attribute
	{
		public MonoModTargetModule(string name)
		{
		}
	}
	[MonoMod__SafeToCopy__]
	internal class MonoMod__SafeToCopy__ : Attribute
	{
	}
	public delegate bool MethodParser(MonoModder modder, MethodBody body, Instruction instr, ref int instri);
	public delegate void MethodRewriter(MonoModder modder, MethodDefinition method);
	public delegate void MethodBodyRewriter(MonoModder modder, MethodBody body, Instruction instr, int instri);
	public delegate ModuleDefinition MissingDependencyResolver(MonoModder modder, ModuleDefinition main, string name, string fullName);
	public delegate void PostProcessor(MonoModder modder);
	public delegate void ModReadEventHandler(MonoModder modder, ModuleDefinition mod);
	public class RelinkMapEntry
	{
		public string Type;

		public string FindableID;

		public RelinkMapEntry()
		{
		}

		public RelinkMapEntry(string type, string findableID)
		{
			Type = type;
			FindableID = findableID;
		}
	}
	public enum DebugSymbolFormat
	{
		Auto,
		MDB,
		PDB
	}
	public class MonoModder : IDisposable
	{
		public static readonly bool IsMono = (object)Type.GetType("Mono.Runtime") != null;

		public static readonly Version Version = typeof(MonoModder).Assembly.GetName().Version;

		public Dictionary<string, object> SharedData = new Dictionary<string, object>();

		public Dictionary<string, object> RelinkMap = new Dictionary<string, object>();

		public Dictionary<string, ModuleDefinition> RelinkModuleMap = new Dictionary<string, ModuleDefinition>();

		public HashSet<string> SkipList = new HashSet<string>(EqualityComparer<string>.Default);

		public Dictionary<string, IMetadataTokenProvider> RelinkMapCache = new Dictionary<string, IMetadataTokenProvider>();

		public Dictionary<string, TypeReference> RelinkModuleMapCache = new Dictionary<string, TypeReference>();

		public Dictionary<string, OpCode> ForceCallMap = new Dictionary<string, OpCode>();

		public ModReadEventHandler OnReadMod;

		public PostProcessor PostProcessors;

		public Dictionary<string, Action<object, object[]>> CustomAttributeHandlers = new Dictionary<string, Action<object, object[]>> { 
		{
			"MonoMod.MonoModPublic",
			delegate
			{
			}
		} };

		public Dictionary<string, Action<object, object[]>> CustomMethodAttributeHandlers = new Dictionary<string, Action<object, object[]>>();

		public MissingDependencyResolver MissingDependencyResolver;

		public MethodParser MethodParser;

		public MethodRewriter MethodRewriter;

		public MethodBodyRewriter MethodBodyRewriter;

		public Stream Input;

		public string InputPath;

		public Stream Output;

		public string OutputPath;

		public List<string> DependencyDirs = new List<string>();

		public ModuleDefinition Module;

		public Dictionary<ModuleDefinition, List<ModuleDefinition>> DependencyMap = new Dictionary<ModuleDefinition, List<ModuleDefinition>>();

		public Dictionary<string, ModuleDefinition> DependencyCache = new Dictionary<string, ModuleDefinition>();

		public Func<ICustomAttributeProvider, TypeReference, bool> ShouldCleanupAttrib;

		public bool LogVerboseEnabled;

		public bool CleanupEnabled;

		public bool PublicEverything;

		public List<ModuleReference> Mods = new List<ModuleReference>();

		public bool Strict;

		public bool MissingDependencyThrow;

		public bool RemovePatchReferences;

		public bool PreventInline;

		public bool? UpgradeMSCORLIB;

		public ReadingMode ReadingMode = (ReadingMode)1;

		public DebugSymbolFormat DebugSymbolOutputFormat;

		public int CurrentRID;

		protected IAssemblyResolver _assemblyResolver;

		protected ReaderParameters _readerParameters;

		protected WriterParameters _writerParameters;

		public bool GACEnabled;

		private string[] _GACPathsNone = new string[0];

		protected string[] _GACPaths;

		protected MethodDefinition _mmOriginalCtor;

		protected MethodDefinition _mmOriginalNameCtor;

		protected MethodDefinition _mmAddedCtor;

		protected MethodDefinition _mmPatchCtor;

		public virtual IAssemblyResolver AssemblyResolver
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Expected O, but got Unknown
				if (_assemblyResolver == null)
				{
					DefaultAssemblyResolver val = new DefaultAssemblyResolver();
					foreach (string dependencyDir in DependencyDirs)
					{
						((BaseAssemblyResolver)val).AddSearchDirectory(dependencyDir);
					}
					_assemblyResolver = (IAssemblyResolver)(object)val;
				}
				return _assemblyResolver;
			}
			set
			{
				_assemblyResolver = value;
			}
		}

		public virtual ReaderParameters ReaderParameters
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: 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_002c: Expected O, but got Unknown
				if (_readerParameters == null)
				{
					_readerParameters = new ReaderParameters(ReadingMode)
					{
						AssemblyResolver = AssemblyResolver,
						ReadSymbols = true
					};
				}
				return _readerParameters;
			}
			set
			{
				_readerParameters = value;
			}
		}

		public virtual WriterParameters WriterParameters
		{
			get
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				//IL_0067: Expected O, but got Unknown
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Expected O, but got Unknown
				if (_writerParameters == null)
				{
					bool flag = DebugSymbolOutputFormat == DebugSymbolFormat.PDB;
					bool flag2 = DebugSymbolOutputFormat == DebugSymbolFormat.MDB;
					if (DebugSymbolOutputFormat == DebugSymbolFormat.Auto)
					{
						if ((PlatformHelper.Current & 0x25) == 37)
						{
							flag = true;
						}
						else
						{
							flag2 = true;
						}
					}
					WriterParameters val = new WriterParameters
					{
						WriteSymbols = true
					};
					object symbolWriterProvider;
					if (!flag)
					{
						if (!flag2)
						{
							symbolWriterProvider = null;
						}
						else
						{
							ISymbolWriterProvider val2 = (ISymbolWriterProvider)new MdbWriterProvider();
							symbolWriterProvider = val2;
						}
					}
					else
					{
						ISymbolWriterProvider val2 = (ISymbolWriterProvider)new NativePdbWriterProvider();
						symbolWriterProvider = val2;
					}
					val.SymbolWriterProvider = (ISymbolWriterProvider)symbolWriterProvider;
					_writerParameters = val;
				}
				return _writerParameters;
			}
			set
			{
				_writerParameters = value;
			}
		}

		public string[] GACPaths
		{
			get
			{
				if (!GACEnabled)
				{
					return _GACPathsNone;
				}
				if (_GACPaths != null)
				{
					return _GACPaths;
				}
				if (!IsMono)
				{
					string environmentVariable = Environment.GetEnvironmentVariable("windir");
					if (string.IsNullOrEmpty(environmentVariable))
					{
						return _GACPaths = _GACPathsNone;
					}
					environmentVariable = Path.Combine(environmentVariable, "Microsoft.NET");
					environmentVariable = Path.Combine(environmentVariable, "assembly");
					_GACPaths = new string[3]
					{
						Path.Combine(environmentVariable, "GAC_32"),
						Path.Combine(environmentVariable, "GAC_64"),
						Path.Combine(environmentVariable, "GAC_MSIL")
					};
				}
				else
				{
					List<string> list = new List<string>();
					string text = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)), "gac");
					if (Directory.Exists(text))
					{
						list.Add(text);
					}
					string environmentVariable2 = Environment.GetEnvironmentVariable("MONO_GAC_PREFIX");
					if (!string.IsNullOrEmpty(environmentVariable2))
					{
						string[] array = environmentVariable2.Split(new char[1] { Path.PathSeparator });
						foreach (string text2 in array)
						{
							if (!string.IsNullOrEmpty(text2))
							{
								string path = text2;
								path = Path.Combine(path, "lib");
								path = Path.Combine(path, "mono");
								path = Path.Combine(path, "gac");
								if (Directory.Exists(path) && !list.Contains(path))
								{
									list.Add(path);
								}
							}
						}
					}
					_GACPaths = list.ToArray();
				}
				return _GACPaths;
			}
			set
			{
				GACEnabled = true;
				_GACPaths = value;
			}
		}

		public MonoModder()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			MethodParser = DefaultParser;
			MissingDependencyResolver = DefaultMissingDependencyResolver;
			PostProcessors = (PostProcessor)Delegate.Combine(PostProcessors, new PostProcessor(DefaultPostProcessor));
			string environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_DEPDIRS");
			if (!string.IsNullOrEmpty(environmentVariable))
			{
				foreach (string item in from dir in environmentVariable.Split(new char[1] { Path.PathSeparator })
					select dir.Trim())
				{
					IAssemblyResolver assemblyResolver = AssemblyResolver;
					IAssemblyResolver obj = ((assemblyResolver is BaseAssemblyResolver) ? assemblyResolver : null);
					if (obj != null)
					{
						((BaseAssemblyResolver)obj).AddSearchDirectory(item);
					}
					DependencyDirs.Add(item);
				}
			}
			LogVerboseEnabled = Environment.GetEnvironmentVariable("MONOMOD_LOG_VERBOSE") == "1";
			CleanupEnabled = Environment.GetEnvironmentVariable("MONOMOD_CLEANUP") != "0";
			PublicEverything = Environment.GetEnvironmentVariable("MONOMOD_PUBLIC_EVERYTHING") == "1";
			PreventInline = Environment.GetEnvironmentVariable("MONOMOD_PREVENTINLINE") == "1";
			Strict = Environment.GetEnvironmentVariable("MONOMOD_STRICT") == "1";
			MissingDependencyThrow = Environment.GetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW") != "0";
			RemovePatchReferences = Environment.GetEnvironmentVariable("MONOMOD_DEPENDENCY_REMOVE_PATCH") != "0";
			string environmentVariable2 = Environment.GetEnvironmentVariable("MONOMOD_DEBUG_FORMAT");
			if (environmentVariable2 != null)
			{
				environmentVariable2 = environmentVariable2.ToLowerInvariant();
				if (environmentVariable2 == "pdb")
				{
					DebugSymbolOutputFormat = DebugSymbolFormat.PDB;
				}
				else if (environmentVariable2 == "mdb")
				{
					DebugSymbolOutputFormat = DebugSymbolFormat.MDB;
				}
			}
			string environmentVariable3 = Environment.GetEnvironmentVariable("MONOMOD_MSCORLIB_UPGRADE");
			UpgradeMSCORLIB = (string.IsNullOrEmpty(environmentVariable3) ? null : new bool?(environmentVariable3 != "0"));
			GACEnabled = Environment.GetEnvironmentVariable("MONOMOD_GAC_ENABLED") != "0";
			MonoModRulesManager.Register(this);
		}

		public virtual void ClearCaches(bool all = false, bool shareable = false, bool moduleSpecific = false)
		{
			if (all || shareable)
			{
				foreach (KeyValuePair<string, ModuleDefinition> item in DependencyCache)
				{
					item.Value.Dispose();
				}
				DependencyCache.Clear();
			}
			if (all || moduleSpecific)
			{
				RelinkMapCache.Clear();
				RelinkModuleMapCache.Clear();
			}
		}

		public virtual void Dispose()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			ClearCaches(all: true);
			ModuleDefinition module = Module;
			if (module != null)
			{
				module.Dispose();
			}
			Module = null;
			((IDisposable)AssemblyResolver)?.Dispose();
			AssemblyResolver = null;
			foreach (ModuleDefinition mod in Mods)
			{
				if ((int)mod != 0)
				{
					mod.Dispose();
				}
			}
			foreach (List<ModuleDefinition> value in DependencyMap.Values)
			{
				foreach (ModuleDefinition item in value)
				{
					if (item != null)
					{
						item.Dispose();
					}
				}
			}
			DependencyMap.Clear();
			Input?.Dispose();
			Output?.Dispose();
		}

		public virtual void Log(object value)
		{
			Log(value.ToString());
		}

		public virtual void Log(string text)
		{
			Console.Write("[MonoMod] ");
			Console.WriteLine(text);
		}

		public virtual void LogVerbose(object value)
		{
			if (LogVerboseEnabled)
			{
				Log(value);
			}
		}

		public virtual void LogVerbose(string text)
		{
			if (LogVerboseEnabled)
			{
				Log(text);
			}
		}

		private static ModuleDefinition _ReadModule(Stream input, ReaderParameters args)
		{
			if (args.ReadSymbols)
			{
				try
				{
					return ModuleDefinition.ReadModule(input, args);
				}
				catch
				{
					args.ReadSymbols = false;
					input.Seek(0L, SeekOrigin.Begin);
				}
			}
			return ModuleDefinition.ReadModule(input, args);
		}

		private static ModuleDefinition _ReadModule(string input, ReaderParameters args)
		{
			if (args.ReadSymbols)
			{
				try
				{
					return ModuleDefinition.ReadModule(input, args);
				}
				catch
				{
					args.ReadSymbols = false;
				}
			}
			return ModuleDefinition.ReadModule(input, args);
		}

		public virtual void Read()
		{
			if (Module != null)
			{
				return;
			}
			if (Input != null)
			{
				Log("Reading input stream into module.");
				Module = _ReadModule(Input, GenReaderParameters(mainModule: true));
			}
			else if (InputPath != null)
			{
				Log("Reading input file into module.");
				IAssemblyResolver assemblyResolver = AssemblyResolver;
				IAssemblyResolver obj = ((assemblyResolver is BaseAssemblyResolver) ? assemblyResolver : null);
				if (obj != null)
				{
					((BaseAssemblyResolver)obj).AddSearchDirectory(Path.GetDirectoryName(InputPath));
				}
				DependencyDirs.Add(Path.GetDirectoryName(InputPath));
				Module = _ReadModule(InputPath, GenReaderParameters(mainModule: true, InputPath));
			}
			string environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_MODS");
			if (string.IsNullOrEmpty(environmentVariable))
			{
				return;
			}
			foreach (string item in from path in environmentVariable.Split(new char[1] { Path.PathSeparator })
				select path.Trim())
			{
				ReadMod(item);
			}
		}

		public virtual void MapDependencies()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			foreach (ModuleDefinition mod in Mods)
			{
				ModuleDefinition main = mod;
				MapDependencies(main);
			}
			MapDependencies(Module);
		}

		public virtual void MapDependencies(ModuleDefinition main)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (DependencyMap.ContainsKey(main))
			{
				return;
			}
			DependencyMap[main] = new List<ModuleDefinition>();
			Enumerator<AssemblyNameReference> enumerator = main.AssemblyReferences.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					AssemblyNameReference current = enumerator.Current;
					MapDependency(main, current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual void MapDependency(ModuleDefinition main, AssemblyNameReference depRef)
		{
			MapDependency(main, depRef.Name, depRef.FullName, depRef);
		}

		public virtual void MapDependency(ModuleDefinition main, string name, string fullName = null, AssemblyNameReference depRef = null)
		{
			if (!DependencyMap.TryGetValue(main, out var value))
			{
				value = (DependencyMap[main] = new List<ModuleDefinition>());
			}
			if (fullName != null && (DependencyCache.TryGetValue(fullName, out var value2) || DependencyCache.TryGetValue(fullName + " [RT:" + main.RuntimeVersion + "]", out value2)))
			{
				LogVerbose("[MapDependency] " + ((ModuleReference)main).Name + " -> " + ((ModuleReference)value2).Name + " ((" + fullName + "), (" + name + ")) from cache");
				value.Add(value2);
				MapDependencies(value2);
				return;
			}
			if (DependencyCache.TryGetValue(name, out value2) || DependencyCache.TryGetValue(name + " [RT:" + main.RuntimeVersion + "]", out value2))
			{
				LogVerbose("[MapDependency] " + ((ModuleReference)main).Name + " -> " + ((ModuleReference)value2).Name + " (" + name + ") from cache");
				value.Add(value2);
				MapDependencies(value2);
				return;
			}
			string text = Path.GetExtension(name).ToLowerInvariant();
			bool flag = text == "pdb" || text == "mdb";
			string text2 = null;
			foreach (string dependencyDir in DependencyDirs)
			{
				text2 = Path.Combine(dependencyDir, name + ".dll");
				if (!File.Exists(text2))
				{
					text2 = Path.Combine(dependencyDir, name + ".exe");
				}
				if (!File.Exists(text2) && !flag)
				{
					text2 = Path.Combine(dependencyDir, name);
				}
				if (File.Exists(text2))
				{
					break;
				}
				text2 = null;
			}
			if (text2 == null && depRef != null)
			{
				try
				{
					AssemblyDefinition obj = AssemblyResolver.Resolve(depRef);
					value2 = ((obj != null) ? obj.MainModule : null);
				}
				catch
				{
				}
				if (value2 != null)
				{
					text2 = value2.FileName;
				}
			}
			if (text2 == null)
			{
				string[] gACPaths = GACPaths;
				for (int i = 0; i < gACPaths.Length; i++)
				{
					text2 = Path.Combine(gACPaths[i], name);
					if (Directory.Exists(text2))
					{
						string[] directories = Directory.GetDirectories(text2);
						int num = 0;
						int num2 = 0;
						for (int j = 0; j < directories.Length; j++)
						{
							string text3 = directories[j];
							if (text3.StartsWith(text2))
							{
								text3 = text3.Substring(text2.Length + 1);
							}
							Match match = Regex.Match(text3, "\\d+");
							if (match.Success)
							{
								int num3 = int.Parse(match.Value);
								if (num3 > num)
								{
									num = num3;
									num2 = j;
								}
							}
						}
						text2 = Path.Combine(directories[num2], name + ".dll");
						break;
					}
					text2 = null;
				}
			}
			if (text2 == null)
			{
				try
				{
					AssemblyDefinition obj3 = AssemblyResolver.Resolve(AssemblyNameReference.Parse(fullName ?? name));
					value2 = ((obj3 != null) ? obj3.MainModule : null);
				}
				catch
				{
				}
				if (value2 != null)
				{
					text2 = value2.FileName;
				}
			}
			if (value2 == null)
			{
				if (text2 != null && File.Exists(text2))
				{
					value2 = _ReadModule(text2, GenReaderParameters(mainModule: false, text2));
				}
				else if ((value2 = MissingDependencyResolver?.Invoke(this, main, name, fullName)) == null)
				{
					return;
				}
			}
			LogVerbose("[MapDependency] " + ((ModuleReference)main).Name + " -> " + ((ModuleReference)value2).Name + " ((" + fullName + "), (" + name + ")) loaded");
			value.Add(value2);
			if (fullName == null)
			{
				fullName = value2.Assembly.FullName;
			}
			DependencyCache[fullName] = value2;
			DependencyCache[name] = value2;
			MapDependencies(value2);
		}

		public virtual ModuleDefinition DefaultMissingDependencyResolver(MonoModder mod, ModuleDefinition main, string name, string fullName)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (MissingDependencyThrow && Environment.GetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW") == "0")
			{
				Log("[MissingDependencyResolver] [WARNING] Use MMILRT.Modder.MissingDependencyThrow instead of setting the env var MONOMOD_DEPENDENCY_MISSING_THROW");
				MissingDependencyThrow = false;
			}
			if (MissingDependencyThrow || Strict)
			{
				throw new RelinkTargetNotFoundException("MonoMod cannot map dependency " + ((ModuleReference)main).Name + " -> ((" + fullName + "), (" + name + ")) - not found", (IMetadataTokenProvider)(object)main, (IMetadataTokenProvider)null);
			}
			return null;
		}

		public virtual void Write(Stream output = null, string outputPath = null)
		{
			output = output ?? Output;
			outputPath = outputPath ?? OutputPath;
			PatchRefsInType(PatchWasHere());
			if (output != null)
			{
				Log("[Write] Writing modded module into output stream.");
				Module.Write(output, WriterParameters);
			}
			else
			{
				Log("[Write] Writing modded module into output file.");
				Module.Write(outputPath, WriterParameters);
			}
		}

		public virtual ReaderParameters GenReaderParameters(bool mainModule, string path = null)
		{
			//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_0013: Expected O, but got Unknown
			ReaderParameters readerParameters = ReaderParameters;
			ReaderParameters val = new ReaderParameters(readerParameters.ReadingMode);
			val.AssemblyResolver = readerParameters.AssemblyResolver;
			val.MetadataResolver = readerParameters.MetadataResolver;
			val.InMemory = readerParameters.InMemory;
			val.MetadataImporterProvider = readerParameters.MetadataImporterProvider;
			val.ReflectionImporterProvider = readerParameters.ReflectionImporterProvider;
			val.ThrowIfSymbolsAreNotMatching = readerParameters.ThrowIfSymbolsAreNotMatching;
			val.ApplyWindowsRuntimeProjections = readerParameters.ApplyWindowsRuntimeProjections;
			val.SymbolStream = readerParameters.SymbolStream;
			val.SymbolReaderProvider = readerParameters.SymbolReaderProvider;
			val.ReadSymbols = readerParameters.ReadSymbols;
			if (path != null && !File.Exists(path + ".mdb") && !File.Exists(Path.ChangeExtension(path, "pdb")))
			{
				val.ReadSymbols = false;
			}
			return val;
		}

		public virtual void ReadMod(string path)
		{
			if (Directory.Exists(path))
			{
				Log("[ReadMod] Loading mod dir: " + path);
				string text = ((ModuleReference)Module).Name.Substring(0, ((ModuleReference)Module).Name.Length - 3);
				string value = text.Replace(" ", "");
				if (!DependencyDirs.Contains(path))
				{
					IAssemblyResolver assemblyResolver = AssemblyResolver;
					IAssemblyResolver obj = ((assemblyResolver is BaseAssemblyResolver) ? assemblyResolver : null);
					if (obj != null)
					{
						((BaseAssemblyResolver)obj).AddSearchDirectory(path);
					}
					DependencyDirs.Add(path);
				}
				string[] files = Directory.GetFiles(path);
				foreach (string text2 in files)
				{
					if ((Path.GetFileName(text2).StartsWith(text) || Path.GetFileName(text2).StartsWith(value)) && text2.ToLower().EndsWith(".mm.dll"))
					{
						ReadMod(text2);
					}
				}
				return;
			}
			Log("[ReadMod] Loading mod: " + path);
			ModuleDefinition val = _ReadModule(path, GenReaderParameters(mainModule: false, path));
			string directoryName = Path.GetDirectoryName(path);
			if (!DependencyDirs.Contains(directoryName))
			{
				IAssemblyResolver assemblyResolver2 = AssemblyResolver;
				IAssemblyResolver obj2 = ((assemblyResolver2 is BaseAssemblyResolver) ? assemblyResolver2 : null);
				if (obj2 != null)
				{
					((BaseAssemblyResolver)obj2).AddSearchDirectory(directoryName);
				}
				DependencyDirs.Add(directoryName);
			}
			Mods.Add((ModuleReference)(object)val);
			OnReadMod?.Invoke(this, val);
		}

		public virtual void ReadMod(Stream stream)
		{
			Log($"[ReadMod] Loading mod: stream#{(uint)stream.GetHashCode()}");
			ModuleDefinition val = _ReadModule(stream, GenReaderParameters(mainModule: false));
			Mods.Add((ModuleReference)(object)val);
			OnReadMod?.Invoke(this, val);
		}

		public virtual void ParseRules(ModuleDefinition mod)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition type = mod.GetType("MonoMod.MonoModRules");
			Type rulesTypeMMILRT = null;
			if (type != null)
			{
				rulesTypeMMILRT = this.ExecuteRules(type);
				mod.Types.Remove(type);
			}
			Enumerator<TypeDefinition> enumerator = mod.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					ParseRulesInType(current, rulesTypeMMILRT);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual void ParseRulesInType(TypeDefinition type, Type rulesTypeMMILRT = null)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			Extensions.GetPatchFullName((MemberReference)(object)type);
			if (!MatchingConditionals((ICustomAttributeProvider)(object)type, Module))
			{
				return;
			}
			CustomAttribute customAttribute = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModCustomAttributeAttribute");
			CustomAttributeArgument val;
			if (customAttribute != null)
			{
				val = customAttribute.ConstructorArguments[0];
				MethodInfo method2 = rulesTypeMMILRT.GetMethod((string)((CustomAttributeArgument)(ref val)).Value);
				CustomAttributeHandlers[((MemberReference)type).FullName] = delegate(object self, object[] args)
				{
					method2.Invoke(self, args);
				};
			}
			customAttribute = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModCustomMethodAttributeAttribute");
			if (customAttribute != null)
			{
				val = customAttribute.ConstructorArguments[0];
				MethodInfo method = rulesTypeMMILRT.GetMethod((string)((CustomAttributeArgument)(ref val)).Value);
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length == 2 && Extensions.IsCompatible(parameters[0].ParameterType, typeof(ILContext)))
				{
					CustomMethodAttributeHandlers[((MemberReference)type).FullName] = delegate(object self, object[] args)
					{
						//IL_0024: Unknown result type (might be due to invalid IL or missing references)
						//IL_002e: Expected O, but got Unknown
						//IL_0029: Unknown result type (might be due to invalid IL or missing references)
						//IL_0033: Expected O, but got Unknown
						//IL_0040: Unknown result type (might be due to invalid IL or missing references)
						//IL_004a: Expected O, but got Unknown
						ILContext il = new ILContext((MethodDefinition)args[0]);
						il.Invoke((Manipulator)delegate
						{
							method.Invoke(self, new object[2]
							{
								il,
								args[1]
							});
						});
						if (il.IsReadOnly)
						{
							il.Dispose();
						}
					};
				}
				else
				{
					CustomMethodAttributeHandlers[((MemberReference)type).FullName] = delegate(object self, object[] args)
					{
						method.Invoke(self, args);
					};
				}
			}
			for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModHook"); val2 != null; val2 = ((ICustomAttributeProvider)(object)type).GetNextCustomAttribute("MonoMod.MonoModHook"))
			{
				ParseLinkFrom((MemberReference)(object)type, val2);
			}
			for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModLinkFrom"); val2 != null; val2 = ((ICustomAttributeProvider)(object)type).GetNextCustomAttribute("MonoMod.MonoModLinkFrom"))
			{
				ParseLinkFrom((MemberReference)(object)type, val2);
			}
			for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModLinkTo"); val2 != null; val2 = ((ICustomAttributeProvider)(object)type).GetNextCustomAttribute("MonoMod.MonoModLinkTo"))
			{
				ParseLinkTo((MemberReference)(object)type, val2);
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModIgnore"))
			{
				return;
			}
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (MatchingConditionals((ICustomAttributeProvider)(object)current, Module))
					{
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current, "MonoMod.MonoModHook"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current).GetNextCustomAttribute("MonoMod.MonoModHook"))
						{
							ParseLinkFrom((MemberReference)(object)current, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current, "MonoMod.MonoModLinkFrom"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current).GetNextCustomAttribute("MonoMod.MonoModLinkFrom"))
						{
							ParseLinkFrom((MemberReference)(object)current, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current, "MonoMod.MonoModLinkTo"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current).GetNextCustomAttribute("MonoMod.MonoModLinkTo"))
						{
							ParseLinkTo((MemberReference)(object)current, val2);
						}
						if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)current, "MonoMod.MonoModForceCall"))
						{
							ForceCallMap[Extensions.GetID((MethodReference)(object)current, (string)null, (string)null, true, false)] = OpCodes.Call;
						}
						else if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)current, "MonoMod.MonoModForceCallvirt"))
						{
							ForceCallMap[Extensions.GetID((MethodReference)(object)current, (string)null, (string)null, true, false)] = OpCodes.Callvirt;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<FieldDefinition> enumerator2 = type.Fields.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FieldDefinition current2 = enumerator2.Current;
					if (MatchingConditionals((ICustomAttributeProvider)(object)current2, Module))
					{
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current2, "MonoMod.MonoModHook"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current2).GetNextCustomAttribute("MonoMod.MonoModHook"))
						{
							ParseLinkFrom((MemberReference)(object)current2, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current2, "MonoMod.MonoModLinkFrom"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current2).GetNextCustomAttribute("MonoMod.MonoModLinkFrom"))
						{
							ParseLinkFrom((MemberReference)(object)current2, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current2, "MonoMod.MonoModLinkTo"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current2).GetNextCustomAttribute("MonoMod.MonoModLinkTo"))
						{
							ParseLinkTo((MemberReference)(object)current2, val2);
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Enumerator<PropertyDefinition> enumerator3 = type.Properties.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					PropertyDefinition current3 = enumerator3.Current;
					if (MatchingConditionals((ICustomAttributeProvider)(object)current3, Module))
					{
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current3, "MonoMod.MonoModHook"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current3).GetNextCustomAttribute("MonoMod.MonoModHook"))
						{
							ParseLinkFrom((MemberReference)(object)current3, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current3, "MonoMod.MonoModLinkFrom"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current3).GetNextCustomAttribute("MonoMod.MonoModLinkFrom"))
						{
							ParseLinkFrom((MemberReference)(object)current3, val2);
						}
						for (CustomAttribute val2 = Extensions.GetCustomAttribute((ICustomAttributeProvider)(object)current3, "MonoMod.MonoModLinkTo"); val2 != null; val2 = ((ICustomAttributeProvider)(object)current3).GetNextCustomAttribute("MonoMod.MonoModLinkTo"))
						{
							ParseLinkTo((MemberReference)(object)current3, val2);
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Enumerator<TypeDefinition> enumerator4 = type.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					TypeDefinition current4 = enumerator4.Current;
					ParseRulesInType(current4, rulesTypeMMILRT);
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
		}

		public virtual void ParseLinkFrom(MemberReference target, CustomAttribute hook)
		{
			//IL_0007: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_003c: 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)
			//IL_005a: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			CustomAttributeArgument val = hook.ConstructorArguments[0];
			string key = (string)((CustomAttributeArgument)(ref val)).Value;
			object value;
			if (target is TypeReference)
			{
				value = Extensions.GetPatchFullName((MemberReference)(TypeReference)target);
			}
			else if (target is MethodReference)
			{
				value = new RelinkMapEntry(Extensions.GetPatchFullName((MemberReference)(object)((MemberReference)(MethodReference)target).DeclaringType), Extensions.GetID((MethodReference)target, (string)null, (string)null, false, false));
			}
			else if (target is FieldReference)
			{
				value = new RelinkMapEntry(Extensions.GetPatchFullName((MemberReference)(object)((MemberReference)(FieldReference)target).DeclaringType), ((MemberReference)(FieldReference)target).Name);
			}
			else
			{
				if (!(target is PropertyReference))
				{
					return;
				}
				value = new RelinkMapEntry(Extensions.GetPatchFullName((MemberReference)(object)((MemberReference)(PropertyReference)target).DeclaringType), ((MemberReference)(PropertyReference)target).Name);
			}
			RelinkMap[key] = value;
		}

		public virtual void ParseLinkTo(MemberReference from, CustomAttribute hook)
		{
			//IL_0063: 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_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_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)
			MemberReference obj = ((from is MethodReference) ? from : null);
			string key = ((obj != null) ? Extensions.GetID((MethodReference)(object)obj, (string)null, (string)null, true, false) : null) ?? Extensions.GetPatchFullName(from);
			CustomAttributeArgument val;
			if (hook.ConstructorArguments.Count == 1)
			{
				Dictionary<string, object> relinkMap = RelinkMap;
				val = hook.ConstructorArguments[0];
				relinkMap[key] = (string)((CustomAttributeArgument)(ref val)).Value;
			}
			else
			{
				Dictionary<string, object> relinkMap2 = RelinkMap;
				val = hook.ConstructorArguments[0];
				string type = (string)((CustomAttributeArgument)(ref val)).Value;
				val = hook.ConstructorArguments[1];
				relinkMap2[key] = new RelinkMapEntry(type, (string)((CustomAttributeArgument)(ref val)).Value);
			}
		}

		public virtual void RunCustomAttributeHandlers(ICustomAttributeProvider cap)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			if (!cap.HasCustomAttributes)
			{
				return;
			}
			CustomAttribute[] array = cap.CustomAttributes.ToArray();
			foreach (CustomAttribute val in array)
			{
				if (CustomAttributeHandlers.TryGetValue(((MemberReference)val.AttributeType).FullName, out var value))
				{
					value?.Invoke(null, new object[2] { cap, val });
				}
				if (cap is MethodReference && CustomMethodAttributeHandlers.TryGetValue(((MemberReference)val.AttributeType).FullName, out value))
				{
					value?.Invoke(null, new object[2]
					{
						(object)(MethodDefinition)cap,
						val
					});
				}
			}
		}

		public virtual void AutoPatch()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			Log("[AutoPatch] Parsing rules in loaded mods");
			foreach (ModuleDefinition mod4 in Mods)
			{
				ModuleDefinition mod = mod4;
				ParseRules(mod);
			}
			Log("[AutoPatch] PrePatch pass");
			foreach (ModuleDefinition mod5 in Mods)
			{
				ModuleDefinition mod2 = mod5;
				PrePatchModule(mod2);
			}
			Log("[AutoPatch] Patch pass");
			foreach (ModuleDefinition mod6 in Mods)
			{
				ModuleDefinition mod3 = mod6;
				PatchModule(mod3);
			}
			Log("[AutoPatch] PatchRefs pass");
			PatchRefs();
			if (PostProcessors != null)
			{
				Delegate[] invocationList = PostProcessors.GetInvocationList();
				for (int i = 0; i < invocationList.Length; i++)
				{
					Log($"[PostProcessor] PostProcessor pass #{i + 1}");
					((PostProcessor)invocationList[i])?.Invoke(this);
				}
			}
		}

		public virtual IMetadataTokenProvider Relinker(IMetadataTokenProvider mtp, IGenericParameterProvider context)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return PostRelinker(MainRelinker(mtp, context) ?? mtp, context) ?? throw new RelinkTargetNotFoundException(mtp, (IMetadataTokenProvider)(object)context);
			}
			catch (Exception ex)
			{
				throw new RelinkFailedException((string)null, ex, mtp, (IMetadataTokenProvider)(object)context);
			}
		}

		public virtual IMetadataTokenProvider MainRelinker(IMetadataTokenProvider mtp, IGenericParameterProvider context)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			TypeReference val = (TypeReference)(object)((mtp is TypeReference) ? mtp : null);
			if (val != null)
			{
				if (((MemberReference)val).Module == Module)
				{
					return (IMetadataTokenProvider)(object)val;
				}
				if (((MemberReference)val).Module != null && !Mods.Contains((ModuleReference)(object)((MemberReference)val).Module))
				{
					return (IMetadataTokenProvider)(object)Module.ImportReference(val);
				}
				val = (TypeReference)(((object)Extensions.SafeResolve(val)) ?? ((object)val));
				TypeReference val2 = FindTypeDeep(Extensions.GetPatchFullName((MemberReference)(object)val));
				if (val2 == null)
				{
					if (RelinkMap.ContainsKey(((MemberReference)val).FullName))
					{
						return null;
					}
					throw new RelinkTargetNotFoundException(mtp, (IMetadataTokenProvider)(object)context);
				}
				return (IMetadataTokenProvider)(object)Module.ImportReference(val2);
			}
			if (mtp is FieldReference || mtp is MethodReference || mtp is PropertyReference || mtp is EventReference)
			{
				return Extensions.ImportReference(Module, mtp);
			}
			throw new InvalidOperationException($"MonoMod default relinker can't handle metadata token providers of the type {((object)mtp).GetType()}");
		}

		public virtual IMetadataTokenProvider PostRelinker(IMetadataTokenProvider mtp, IGenericParameterProvider context)
		{
			return ResolveRelinkTarget(mtp) ?? mtp;
		}

		public virtual IMetadataTokenProvider ResolveRelinkTarget(IMetadataTokenProvider mtp, bool relink = true, bool relinkModule = true)
		{
			//IL_000b: 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_002f: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_004b: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_023c: Expected O, but got Unknown
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			string text = null;
			string text2;
			if (mtp is TypeReference)
			{
				text2 = ((MemberReference)(TypeReference)mtp).FullName;
			}
			else if (mtp is MethodReference)
			{
				text2 = Extensions.GetID((MethodReference)mtp, (string)null, (string)null, true, false);
				text = Extensions.GetID((MethodReference)mtp, (string)null, (string)null, true, true);
			}
			else if (mtp is FieldReference)
			{
				text2 = ((MemberReference)(FieldReference)mtp).FullName;
			}
			else
			{
				if (!(mtp is PropertyReference))
				{
					return null;
				}
				text2 = ((MemberReference)(PropertyReference)mtp).FullName;
			}
			if (RelinkMapCache.TryGetValue(text2, out var value))
			{
				return value;
			}
			if (relink && (RelinkMap.TryGetValue(text2, out var value2) || (text != null && RelinkMap.TryGetValue(text, out value2))))
			{
				if (value2 is IMetadataTokenProvider)
				{
					return RelinkMapCache[text2] = Extensions.ImportReference(Module, (IMetadataTokenProvider)value2);
				}
				if (value2 is RelinkMapEntry)
				{
					string type = ((RelinkMapEntry)value2).Type;
					string findableID = ((RelinkMapEntry)value2).FindableID;
					TypeReference obj = FindTypeDeep(type);
					TypeDefinition val2 = ((obj != null) ? Extensions.SafeResolve(obj) : null);
					if (val2 == null)
					{
						return RelinkMapCache[text2] = ResolveRelinkTarget(mtp, relink: false, relinkModule);
					}
					value2 = Extensions.FindMethod(val2, findableID, true) ?? ((object)Extensions.FindField(val2, findableID)) ?? ((object)(Extensions.FindProperty(val2, findableID) ?? null));
					if (value2 == null)
					{
						if (Strict)
						{
							throw new RelinkTargetNotFoundException(string.Format("{0} ({1}, {2}) (remap: {3})", "MonoMod relinker failed finding", type, findableID, mtp), mtp, (IMetadataTokenProvider)null);
						}
						return null;
					}
					return RelinkMapCache[text2] = Extensions.ImportReference(Module, (IMetadataTokenProvider)value2);
				}
				if (value2 is string && mtp is TypeReference)
				{
					IMetadataTokenProvider val5 = (IMetadataTokenProvider)(object)FindTypeDeep((string)value2);
					if (val5 == null)
					{
						if (Strict)
						{
							throw new RelinkTargetNotFoundException(string.Format("{0} {1} (remap: {2})", "MonoMod relinker failed finding", value2, mtp), mtp, (IMetadataTokenProvider)null);
						}
						return null;
					}
					value2 = Extensions.ImportReference(Module, ResolveRelinkTarget(val5, relink: false, relinkModule) ?? val5);
				}
				if (value2 is IMetadataTokenProvider)
				{
					Dictionary<string, IMetadataTokenProvider> relinkMapCache = RelinkMapCache;
					string key = text2;
					IMetadataTokenProvider val6 = (IMetadataTokenProvider)value2;
					IMetadataTokenProvider result = val6;
					relinkMapCache[key] = val6;
					return result;
				}
				throw new InvalidOperationException($"MonoMod doesn't support RelinkMap value of type {value2.GetType()} (remap: {mtp})");
			}
			if (relinkModule && mtp is TypeReference)
			{
				if (RelinkModuleMapCache.TryGetValue(text2, out var value3))
				{
					return (IMetadataTokenProvider)(object)value3;
				}
				value3 = (TypeReference)mtp;
				if (RelinkModuleMap.TryGetValue(value3.Scope.Name, out var value4))
				{
					TypeReference type2 = (TypeReference)(object)value4.GetType(((MemberReference)value3).FullName);
					if (type2 == null)
					{
						if (Strict)
						{
							throw new RelinkTargetNotFoundException(string.Format("{0} {1} (remap: {2})", "MonoMod relinker failed finding", ((MemberReference)value3).FullName, mtp), mtp, (IMetadataTokenProvider)null);
						}
						return null;
					}
					return (IMetadataTokenProvider)(object)(RelinkModuleMapCache[text2] = Module.ImportReference(type2));
				}
				return (IMetadataTokenProvider)(object)Module.ImportReference(value3);
			}
			return null;
		}

		public virtual bool DefaultParser(MonoModder mod, MethodBody body, Instruction instr, ref int instri)
		{
			return true;
		}

		public virtual TypeReference FindType(string name)
		{
			return FindType(Module, name, new Stack<ModuleDefinition>()) ?? Module.GetType(name, false);
		}

		public virtual TypeReference FindType(string name, bool runtimeName)
		{
			return FindType(Module, name, new Stack<ModuleDefinition>()) ?? Module.GetType(name, runtimeName);
		}

		protected virtual TypeReference FindType(ModuleDefinition main, string fullName, Stack<ModuleDefinition> crawled)
		{
			TypeReference type;
			if ((type = main.GetType(fullName, false)) != null)
			{
				return type;
			}
			if (fullName.StartsWith("<PrivateImplementationDetails>/"))
			{
				return null;
			}
			if (crawled.Contains(main))
			{
				return null;
			}
			crawled.Push(main);
			foreach (ModuleDefinition item in DependencyMap[main])
			{
				if ((!RemovePatchReferences || !((AssemblyNameReference)item.Assembly.Name).Name.EndsWith(".mm")) && (type = FindType(item, fullName, crawled)) != null)
				{
					return type;
				}
			}
			return null;
		}

		public virtual TypeReference FindTypeDeep(string name)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			TypeReference val = FindType(name, runtimeName: false);
			if (val != null)
			{
				return val;
			}
			Stack<ModuleDefinition> crawled = new Stack<ModuleDefinition>();
			val = null;
			foreach (ModuleDefinition mod in Mods)
			{
				ModuleDefinition key = mod;
				foreach (ModuleDefinition item in DependencyMap[key])
				{
					if ((val = FindType(item, name, crawled)) != null)
					{
						IMetadataScope scope = val.Scope;
						AssemblyNameReference dllRef = (AssemblyNameReference)(object)((scope is AssemblyNameReference) ? scope : null);
						if (dllRef != null && !((IEnumerable<AssemblyNameReference>)Module.AssemblyReferences).Any((AssemblyNameReference n) => n.Name == dllRef.Name))
						{
							Module.AssemblyReferences.Add(dllRef);
						}
						return Module.ImportReference(val);
					}
				}
			}
			return null;
		}

		public virtual void PrePatchModule(ModuleDefinition mod)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0090: 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_0120: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			Enumerator<TypeDefinition> enumerator = mod.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					PrePatchType(current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<ModuleReference> enumerator2 = mod.ModuleReferences.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ModuleReference current2 = enumerator2.Current;
					if (!Module.ModuleReferences.Contains(current2))
					{
						Module.ModuleReferences.Add(current2);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Enumerator<Resource> enumerator3 = mod.Resources.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					Resource current3 = enumerator3.Current;
					if (current3 is EmbeddedResource)
					{
						Module.Resources.Add((Resource)new EmbeddedResource(current3.Name.StartsWith(((AssemblyNameReference)mod.Assembly.Name).Name) ? (((AssemblyNameReference)Module.Assembly.Name).Name + current3.Name.Substring(((AssemblyNameReference)mod.Assembly.Name).Name.Length)) : current3.Name, current3.Attributes, ((EmbeddedResource)current3).GetResourceData()));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
		}

		public virtual void PrePatchType(TypeDefinition type, bool forceAdd = false)
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0119: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			string patchFullName = Extensions.GetPatchFullName((MemberReference)(object)type);
			if ((((TypeReference)type).Namespace != "MonoMod" && Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModIgnore")) || SkipList.Contains(patchFullName) || !MatchingConditionals((ICustomAttributeProvider)(object)type, Module) || (((MemberReference)type).FullName == "MonoMod.MonoModRules" && !forceAdd))
			{
				return;
			}
			TypeReference val = (forceAdd ? null : Module.GetType(patchFullName, false));
			TypeDefinition val2 = ((val != null) ? Extensions.SafeResolve(val) : null);
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModReplace") || Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModRemove"))
			{
				if (val2 != null)
				{
					if (val2.DeclaringType == null)
					{
						Module.Types.Remove(val2);
					}
					else
					{
						val2.DeclaringType.NestedTypes.Remove(val2);
					}
				}
				if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModRemove"))
				{
					return;
				}
			}
			else if (val != null)
			{
				PrePatchNested(type);
				return;
			}
			LogVerbose("[PrePatchType] Adding " + patchFullName + " to the target module.");
			TypeDefinition val3 = new TypeDefinition(((TypeReference)type).Namespace, ((MemberReference)type).Name, type.Attributes, type.BaseType);
			Enumerator<GenericParameter> enumerator = ((TypeReference)type).GenericParameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					GenericParameter current = enumerator.Current;
					((TypeReference)val3).GenericParameters.Add(Extensions.Clone(current));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<InterfaceImplementation> enumerator2 = type.Interfaces.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					InterfaceImplementation current2 = enumerator2.Current;
					val3.Interfaces.Add(current2);
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			val3.ClassSize = type.ClassSize;
			if (type.DeclaringType != null)
			{
				val3.DeclaringType = Extensions.Relink((TypeReference)(object)type.DeclaringType, new Relinker(Relinker), (IGenericParameterProvider)(object)val3).Resolve();
				val3.DeclaringType.NestedTypes.Add(val3);
			}
			else
			{
				Module.Types.Add(val3);
			}
			val3.PackingSize = type.PackingSize;
			Extensions.AddRange<SecurityDeclaration>(val3.SecurityDeclarations, (IEnumerable<SecurityDeclaration>)type.SecurityDeclarations);
			val3.CustomAttributes.Add(new CustomAttribute(GetMonoModAddedCtor()));
			val = (TypeReference)(object)val3;
			PrePatchNested(type);
		}

		protected virtual void PrePatchNested(TypeDefinition type)
		{
			for (int i = 0; i < type.NestedTypes.Count; i++)
			{
				PrePatchType(type.NestedTypes[i]);
			}
		}

		public virtual void PatchModule(ModuleDefinition mod)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeDefinition> enumerator = mod.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if ((((TypeReference)current).Namespace == "MonoMod" || ((TypeReference)current).Namespace.StartsWith("MonoMod.")) && ((MemberReference)current.BaseType).FullName == "System.Attribute")
					{
						PatchType(current);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			enumerator = mod.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current2 = enumerator.Current;
					if ((!(((TypeReference)current2).Namespace == "MonoMod") && !((TypeReference)current2).Namespace.StartsWith("MonoMod.")) || !(((MemberReference)current2.BaseType).FullName == "System.Attribute"))
					{
						PatchType(current2);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual void PatchType(TypeDefinition type)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			string patchFullName = Extensions.GetPatchFullName((MemberReference)(object)type);
			TypeReference type2 = Module.GetType(patchFullName, false);
			if (type2 == null)
			{
				return;
			}
			TypeDefinition val = ((type2 != null) ? Extensions.SafeResolve(type2) : null);
			Enumerator<CustomAttribute> enumerator;
			if ((((TypeReference)type).Namespace != "MonoMod" && Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModIgnore")) || SkipList.Contains(patchFullName) || !MatchingConditionals((ICustomAttributeProvider)(object)type, Module))
			{
				if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModIgnore") && val != null)
				{
					enumerator = type.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CustomAttribute current = enumerator.Current;
							if (CustomAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName))
							{
								val.CustomAttributes.Add(Extensions.Clone(current));
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				PatchNested(type);
				return;
			}
			if (patchFullName == ((MemberReference)type).FullName)
			{
				LogVerbose("[PatchType] Patching type " + patchFullName);
			}
			else
			{
				LogVerbose("[PatchType] Patching type " + patchFullName + " (prefixed: " + ((MemberReference)type).FullName + ")");
			}
			enumerator = type.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current2 = enumerator.Current;
					if (!Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)val, ((MemberReference)current2.AttributeType).FullName))
					{
						val.CustomAttributes.Add(Extensions.Clone(current2));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			HashSet<MethodDefinition> hashSet = new HashSet<MethodDefinition>();
			Enumerator<PropertyDefinition> enumerator2 = type.Properties.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					PropertyDefinition current3 = enumerator2.Current;
					PatchProperty(val, current3, hashSet);
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			HashSet<MethodDefinition> hashSet2 = new HashSet<MethodDefinition>();
			Enumerator<EventDefinition> enumerator3 = type.Events.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					EventDefinition current4 = enumerator3.Current;
					PatchEvent(val, current4, hashSet2);
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Enumerator<MethodDefinition> enumerator4 = type.Methods.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					MethodDefinition current5 = enumerator4.Current;
					if (!hashSet.Contains(current5) && !hashSet2.Contains(current5))
					{
						PatchMethod(val, current5);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)type, "MonoMod.MonoModEnumReplace"))
			{
				int num = 0;
				while (num < val.Fields.Count)
				{
					if (((MemberReference)val.Fields[num]).Name == "value__")
					{
						num++;
					}
					else
					{
						val.Fields.RemoveAt(num);
					}
				}
			}
			Enumerator<FieldDefinition> enumerator5 = type.Fields.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					FieldDefinition current6 = enumerator5.Current;
					PatchField(val, current6);
				}
			}
			finally
			{
				((IDisposable)enumerator5).Dispose();
			}
			PatchNested(type);
		}

		protected virtual void PatchNested(TypeDefinition type)
		{
			for (int i = 0; i < type.NestedTypes.Count; i++)
			{
				PatchType(type.NestedTypes[i]);
			}
		}

		public virtual void PatchProperty(TypeDefinition targetType, PropertyDefinition prop, HashSet<MethodDefinition> propMethods = null)
		{
			//IL_006e: 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_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Expected O, but got Unknown
			//IL_022b: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_02b5: Expected O, but got Unknown
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			if (!MatchingConditionals((ICustomAttributeProvider)(object)prop, Module))
			{
				return;
			}
			((MemberReference)prop).Name = Extensions.GetPatchName((MemberReference)(object)prop);
			PropertyDefinition val = Extensions.FindProperty(targetType, ((MemberReference)prop).Name);
			string text = "<" + ((MemberReference)prop).Name + ">__BackingField";
			FieldDefinition val2 = Extensions.FindField(prop.DeclaringType, text);
			FieldDefinition val3 = Extensions.FindField(targetType, text);
			Enumerator<CustomAttribute> enumerator;
			Enumerator<MethodDefinition> enumerator2;
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)prop, "MonoMod.MonoModIgnore"))
			{
				if (val != null)
				{
					enumerator = prop.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CustomAttribute current = enumerator.Current;
							if (CustomAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName))
							{
								val.CustomAttributes.Add(Extensions.Clone(current));
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				if (val2 != null)
				{
					val2.DeclaringType.Fields.Remove(val2);
				}
				if (prop.GetMethod != null)
				{
					propMethods?.Add(prop.GetMethod);
				}
				if (prop.SetMethod != null)
				{
					propMethods?.Add(prop.SetMethod);
				}
				enumerator2 = prop.OtherMethods.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodDefinition current2 = enumerator2.Current;
						propMethods?.Add(current2);
					}
					return;
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)prop, "MonoMod.MonoModRemove") || Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)prop, "MonoMod.MonoModReplace"))
			{
				if (val != null)
				{
					targetType.Properties.Remove(val);
					if (val3 != null)
					{
						targetType.Fields.Remove(val3);
					}
					if (val.GetMethod != null)
					{
						targetType.Methods.Remove(val.GetMethod);
					}
					if (val.SetMethod != null)
					{
						targetType.Methods.Remove(val.SetMethod);
					}
					enumerator2 = val.OtherMethods.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							MethodDefinition current3 = enumerator2.Current;
							targetType.Methods.Remove(current3);
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
				}
				if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)prop, "MonoMod.MonoModRemove"))
				{
					return;
				}
			}
			if (val == null)
			{
				PropertyDefinition val4 = new PropertyDefinition(((MemberReference)prop).Name, prop.Attributes, ((PropertyReference)prop).PropertyType);
				val = val4;
				PropertyDefinition val5 = val4;
				val5.CustomAttributes.Add(new CustomAttribute(GetMonoModAddedCtor()));
				Enumerator<ParameterDefinition> enumerator3 = ((PropertyReference)prop).Parameters.GetEnumerator();
				try
				{
					while (enumerator3.MoveNext())
					{
						ParameterDefinition current4 = enumerator3.Current;
						((PropertyReference)val5).Parameters.Add(Extensions.Clone(current4));
					}
				}
				finally
				{
					((IDisposable)enumerator3).Dispose();
				}
				val5.DeclaringType = targetType;
				targetType.Properties.Add(val5);
				if (val2 != null)
				{
					FieldDefinition val6 = new FieldDefinition(text, val2.Attributes, ((FieldReference)val2).FieldType);
					val3 = val6;
					FieldDefinition val7 = val6;
					targetType.Fields.Add(val7);
				}
			}
			enumerator = prop.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current5 = enumerator.Current;
					val.CustomAttributes.Add(Extensions.Clone(current5));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			MethodDefinition getMethod = prop.GetMethod;
			MethodDefinition getMethod2;
			if (getMethod != null && (getMethod2 = PatchMethod(targetType, getMethod)) != null)
			{
				val.GetMethod = getMethod2;
				propMethods?.Add(getMethod);
			}
			MethodDefinition setMethod = prop.SetMethod;
			if (setMethod != null && (getMethod2 = PatchMethod(targetType, setMethod)) != null)
			{
				val.SetMethod = getMethod2;
				propMethods?.Add(setMethod);
			}
			enumerator2 = prop.OtherMethods.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					MethodDefinition current6 = enumerator2.Current;
					if ((getMethod2 = PatchMethod(targetType, current6)) != null)
					{
						val.OtherMethods.Add(getMethod2);
						propMethods?.Add(current6);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
		}

		public virtual void PatchEvent(TypeDefinition targetType, EventDefinition srcEvent, HashSet<MethodDefinition> propMethods = null)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Expected O, but got Unknown
			//IL_0252: Expected O, but got Unknown
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			((MemberReference)srcEvent).Name = Extensions.GetPatchName((MemberReference)(object)srcEvent);
			EventDefinition val = Extensions.FindEvent(targetType, ((MemberReference)srcEvent).Name);
			string text = "<" + ((MemberReference)srcEvent).Name + ">__BackingField";
			FieldDefinition val2 = Extensions.FindField(srcEvent.DeclaringType, text);
			FieldDefinition val3 = Extensions.FindField(targetType, text);
			Enumerator<CustomAttribute> enumerator;
			Enumerator<MethodDefinition> enumerator2;
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)srcEvent, "MonoMod.MonoModIgnore"))
			{
				if (val != null)
				{
					enumerator = srcEvent.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CustomAttribute current = enumerator.Current;
							if (CustomAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName))
							{
								val.CustomAttributes.Add(Extensions.Clone(current));
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				if (val2 != null)
				{
					val2.DeclaringType.Fields.Remove(val2);
				}
				if (srcEvent.AddMethod != null)
				{
					propMethods?.Add(srcEvent.AddMethod);
				}
				if (srcEvent.RemoveMethod != null)
				{
					propMethods?.Add(srcEvent.RemoveMethod);
				}
				if (srcEvent.InvokeMethod != null)
				{
					propMethods?.Add(srcEvent.InvokeMethod);
				}
				enumerator2 = srcEvent.OtherMethods.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodDefinition current2 = enumerator2.Current;
						propMethods?.Add(current2);
					}
					return;
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)srcEvent, "MonoMod.MonoModRemove") || Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)srcEvent, "MonoMod.MonoModReplace"))
			{
				if (val != null)
				{
					targetType.Events.Remove(val);
					if (val3 != null)
					{
						targetType.Fields.Remove(val3);
					}
					if (val.AddMethod != null)
					{
						targetType.Methods.Remove(val.AddMethod);
					}
					if (val.RemoveMethod != null)
					{
						targetType.Methods.Remove(val.RemoveMethod);
					}
					if (val.InvokeMethod != null)
					{
						targetType.Methods.Remove(val.InvokeMethod);
					}
					if (val.OtherMethods != null)
					{
						enumerator2 = val.OtherMethods.GetEnumerator();
						try
						{
							while (enumerator2.MoveNext())
							{
								MethodDefinition current3 = enumerator2.Current;
								targetType.Methods.Remove(current3);
							}
						}
						finally
						{
							((IDisposable)enumerator2).Dispose();
						}
					}
				}
				if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)srcEvent, "MonoMod.MonoModRemove"))
				{
					return;
				}
			}
			if (val == null)
			{
				EventDefinition val4 = new EventDefinition(((MemberReference)srcEvent).Name, srcEvent.Attributes, ((EventReference)srcEvent).EventType);
				val = val4;
				EventDefinition val5 = val4;
				val5.CustomAttributes.Add(new CustomAttribute(GetMonoModAddedCtor()));
				val5.DeclaringType = targetType;
				targetType.Events.Add(val5);
				if (val2 != null)
				{
					FieldDefinition val6 = new FieldDefinition(text, val2.Attributes, ((FieldReference)val2).FieldType);
					targetType.Fields.Add(val6);
				}
			}
			enumerator = srcEvent.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current4 = enumerator.Current;
					val.CustomAttributes.Add(Extensions.Clone(current4));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			MethodDefinition addMethod = srcEvent.AddMethod;
			MethodDefinition addMethod2;
			if (addMethod != null && (addMethod2 = PatchMethod(targetType, addMethod)) != null)
			{
				val.AddMethod = addMethod2;
				propMethods?.Add(addMethod);
			}
			MethodDefinition removeMethod = srcEvent.RemoveMethod;
			if (removeMethod != null && (addMethod2 = PatchMethod(targetType, removeMethod)) != null)
			{
				val.RemoveMethod = addMethod2;
				propMethods?.Add(removeMethod);
			}
			MethodDefinition invokeMethod = srcEvent.InvokeMethod;
			if (invokeMethod != null && (addMethod2 = PatchMethod(targetType, invokeMethod)) != null)
			{
				val.InvokeMethod = addMethod2;
				propMethods?.Add(invokeMethod);
			}
			enumerator2 = srcEvent.OtherMethods.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					MethodDefinition current5 = enumerator2.Current;
					if ((addMethod2 = PatchMethod(targetType, current5)) != null)
					{
						val.OtherMethods.Add(addMethod2);
						propMethods?.Add(current5);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
		}

		public virtual void PatchField(TypeDefinition targetType, FieldDefinition field)
		{
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			string patchFullName = Extensions.GetPatchFullName((MemberReference)(object)field.DeclaringType);
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)field, "MonoMod.MonoModNoNew") || SkipList.Contains(patchFullName + "::" + ((MemberReference)field).Name) || !MatchingConditionals((ICustomAttributeProvider)(object)field, Module))
			{
				return;
			}
			((MemberReference)field).Name = Extensions.GetPatchName((MemberReference)(object)field);
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)field, "MonoMod.MonoModRemove") || Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)field, "MonoMod.MonoModReplace"))
			{
				FieldDefinition val = Extensions.FindField(targetType, ((MemberReference)field).Name);
				if (val != null)
				{
					targetType.Fields.Remove(val);
				}
				if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)field, "MonoMod.MonoModRemove"))
				{
					return;
				}
			}
			FieldDefinition val2 = Extensions.FindField(targetType, ((MemberReference)field).Name);
			Enumerator<CustomAttribute> enumerator;
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)field, "MonoMod.MonoModIgnore") && val2 != null)
			{
				enumerator = field.CustomAttributes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CustomAttribute current = enumerator.Current;
						if (CustomAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName))
						{
							val2.CustomAttributes.Add(Extensions.Clone(current));
						}
					}
					return;
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			if (val2 == null)
			{
				val2 = new FieldDefinition(((MemberReference)field).Name, field.Attributes, ((FieldReference)field).FieldType);
				val2.CustomAttributes.Add(new CustomAttribute(GetMonoModAddedCtor()));
				val2.InitialValue = field.InitialValue;
				if (field.HasConstant)
				{
					val2.Constant = field.Constant;
				}
				targetType.Fields.Add(val2);
			}
			enumerator = field.CustomAttributes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					CustomAttribute current2 = enumerator.Current;
					val2.CustomAttributes.Add(Extensions.Clone(current2));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual MethodDefinition PatchMethod(TypeDefinition targetType, MethodDefinition method)
		{
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Expected O, but got Unknown
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_0569: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Expected O, but got Unknown
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Expected O, but got Unknown
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_0635: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Expected O, but got Unknown
			if (((MemberReference)method).Name.StartsWith("orig_") || Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModOriginal"))
			{
				return null;
			}
			if (!AllowedSpecialName(method, targetType) || !MatchingConditionals((ICustomAttributeProvider)(object)method, Module))
			{
				return null;
			}
			string patchFullName = Extensions.GetPatchFullName((MemberReference)(object)targetType);
			if (SkipList.Contains(Extensions.GetID((MethodReference)(object)method, (string)null, patchFullName, true, false)))
			{
				return null;
			}
			((MemberReference)method).Name = Extensions.GetPatchName((MemberReference)(object)method);
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModConstructor"))
			{
				if (!method.IsSpecialName && !Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModOriginalName"))
				{
					CustomAttribute val = new CustomAttribute(GetMonoModOriginalNameCtor());
					val.ConstructorArguments.Add(new CustomAttributeArgument(Module.TypeSystem.String, (object)("orig_" + ((MemberReference)method).Name)));
					method.CustomAttributes.Add(val);
				}
				((MemberReference)method).Name = (method.IsStatic ? ".cctor" : ".ctor");
				method.IsSpecialName = true;
				method.IsRuntimeSpecialName = true;
			}
			MethodDefinition val2 = Extensions.FindMethod(targetType, Extensions.GetID((MethodReference)(object)method, (string)null, patchFullName, true, false), true);
			MethodDefinition obj = method;
			string text = patchFullName;
			MethodDefinition val3 = Extensions.FindMethod(targetType, Extensions.GetID((MethodReference)(object)obj, method.GetOriginalName(), text, true, false), true);
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModIgnore"))
			{
				if (val2 != null)
				{
					Enumerator<CustomAttribute> enumerator = method.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CustomAttribute current = enumerator.Current;
							if (CustomAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName) || CustomMethodAttributeHandlers.ContainsKey(((MemberReference)current.AttributeType).FullName))
							{
								val2.CustomAttributes.Add(Extensions.Clone(current));
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				return null;
			}
			if (val2 == null && Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModNoNew"))
			{
				return null;
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModRemove"))
			{
				if (val2 != null)
				{
					targetType.Methods.Remove(val2);
				}
				return null;
			}
			if (Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModReplace"))
			{
				if (val2 != null)
				{
					val2.CustomAttributes.Clear();
					val2.Attributes = method.Attributes;
					val2.IsPInvokeImpl = method.IsPInvokeImpl;
					val2.ImplAttributes = method.ImplAttributes;
				}
			}
			else if (val2 != null && val3 == null)
			{
				val3 = Extensions.Clone(val2, (MethodDefinition)null);
				((MemberReference)val3).Name = method.GetOriginalName();
				val3.Attributes = (MethodAttributes)(val2.Attributes & 0xF7FF & 0xEFFF);
				((MemberReference)val3).MetadataToken = GetMetadataToken((TokenType)100663296);
				val3.IsVirtual = false;
				val3.Overrides.Clear();
				Enumerator<MethodReference> enumerator2 = method.Overrides.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodReference current2 = enumerator2.Current;
						val3.Overrides.Add(current2);
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
				val3.CustomAttributes.Add(new CustomAttribute(GetMonoModOriginalCtor()));
				MethodDefinition val4 = Extensions.FindMethod(method.DeclaringType, Extensions.GetID((MethodReference)(object)method, method.GetOriginalName(), (string)null, true, false), true);
				if (val4 != null)
				{
					Enumerator<CustomAttribute> enumerator = val4.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CustomAttribute current3 = enumerator.Current;
							if (CustomAttributeHandlers.ContainsKey(((MemberReference)current3.AttributeType).FullName) || CustomMethodAttributeHandlers.ContainsKey(((MemberReference)current3.AttributeType).FullName))
							{
								val3.CustomAttributes.Add(Extensions.Clone(current3));
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
				}
				targetType.Methods.Add(val3);
			}
			if (val3 != null && method.IsConstructor && method.IsStatic && method.HasBody && !Extensions.HasCustomAttribute((ICustomAttributeProvider)(object)method, "MonoMod.MonoModConstructor"))
			{
				Collection<Instruction> instructions = method.Body.Instructions;
				ILProcessor iLProcessor = method.Body.GetILProcessor();
				iLProcessor.InsertBefore(instructions[instructions.Count - 1], iLProcessor.Create(OpCodes.Call, (MethodReference)(object)val3));
			}
			if (val2 != null)
			{
				val2.Body = Extensions.Clone(method.Body, val2);
				val2.IsManaged = method.IsManaged;
				val2.IsIL = method.IsIL;
				val2.IsNative = method.IsNative;
				val2.PInvokeInfo = method.PInvokeInfo;
				val2.IsPreserveSig = method.IsPreserveSig;
				val2.IsInternalCall = method.IsInternalCall;
				val2.IsPInvokeImpl = method.IsPInvokeImpl;
				Enumerator<CustomAttribute> enumerator = method.CustomAttributes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CustomAttribute current4 = enumerator.Current;
						val2.CustomAttributes.Add(Extensions.Clone(current4));
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				method = val2;
			}
			else
			{
				MethodDefinition val5 = new MethodDefinition(((MemberReference)method).Name, method.Attributes, Module.TypeSystem.Void);
				((MemberReference)val5).MetadataToken = GetMetadataToken((TokenType)100663296);
				((MethodReference)val5).CallingConvention = ((MethodReference)method).CallingConvention;
				((MethodReference)val5).ExplicitThis = ((MethodReference)method).ExplicitThis;
				((MethodReference)val5).MethodReturnType = ((MethodReference)method).MethodReturnType;
				val5.Attributes = method.Attributes;
				val5.ImplAttributes = method.ImplAttributes;
				val5.SemanticsAttributes = method.SemanticsAttributes;
				val5.DeclaringType = targetType;
				((MethodReference)val5).ReturnType = ((MethodReference)method).ReturnType;
				val5.Body = Extensions.Clone(method.Body, val5);
				val5.PInvokeInfo = method.PInvokeInfo;
				val5.IsPInvokeImpl = method.IsPInvokeImpl;
				Enumerator<GenericParameter> enumerator3 = ((MethodReference)method).GenericParameters.GetEnumerator();
				try
				{
					while (enumerator3.MoveNext())
					{
						GenericParameter current5 = enumerator3.Current;
						((MethodReference)val5).GenericParameters.Add(Extensions.Clone(current5));
					}
				}
				finally
				{
					((IDisposable)enumerator3).Dispose();
				}
				Enumerator<ParameterDefinition> enumerator4 = ((MethodReference)method).Parameters.GetEnumerator();
				try
				{
					while (enumerator4.MoveNext())
					{
						ParameterDefinition current6 = enumerator4.Current;
						((MethodReference)val5).Parameters.Add(Extensions.Clone(current6));
					}
				}
				finally
				{
					((IDisposable)enumerator4).Dispose();
				}
				Enumerator<CustomAttribute> enumerator = method.CustomAttributes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CustomAttribute current7 = enumerator.Current;
						val5.CustomAttributes.Add(Extensions.Clone(current7));
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				Enumerator<MethodReference> enumerator2 = method.Overrides.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						MethodReference current8 = enumerator2.Current;
						val5.Overrides.Add(current8);
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
				val5.CustomAttributes.Add(new CustomAttribute(GetMonoModAddedCtor()));
				targetType.Methods.Add(val5);
				method = val5;
			}
			if (val3 != null)
			{
				CustomAttribute val6 = new CustomAttribute(GetMonoModOriginalNameCtor());
				val6.ConstructorArguments.Add(new CustomAttributeArgument(Module.TypeSystem.String, (object)((MemberReference)val3).Name));
				method.CustomAttributes.Add(val6);
			}
			return method;
		}

		public virtual void PatchRefs()
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			if (!UpgradeMSCORLIB.HasValue)
			{
				Version fckUnity = new Version(2, 0, 5, 0);
				UpgradeMSCORLIB = ((IEnumerable<AssemblyNameReference>)Module.AssemblyReferences).Any((AssemblyNameReference x) => x.Version == fckUnity);
			}
			if (UpgradeMSCORLIB.Value)
			{
				List<AssemblyNameReference> list = new List<AssemblyNameReference>();
				for (int i = 0; i < Module.AssemblyReferences.Count; i++)
				{
					AssemblyNameReference val = Module.AssemblyReferences[i];
					if (val.Name == "mscorlib")
					{
						list.Add(val);
					}
				}
				if (list.Count > 1)
				{
					AssemblyNameReference val2 = list.OrderByDescending((AssemblyNameReference x) => x.Version).First();
					if (DependencyCache.TryGetValue(val2.FullName, out var value))
					{
						for (int j = 0; j < Module.AssemblyReferences.Count; j++)
						{
							AssemblyNameReference val3 = Module.AssemblyReferences[j];
							if (val3.Name == "mscorlib" && val2.Version > val3.Version)
							{
								LogVerbose("[PatchRefs] Removing and relinking duplicate mscorlib: " + val3.Version);
								RelinkModuleMap[val3.FullName] = value;
								Module.AssemblyReferences.RemoveAt(j);
								j--;
							}
						}
					}
				}
			}
			Enumerator<TypeDefinition> enumerator = Module.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					PatchRefsInType(current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual void PatchRefs(ModuleDefinition mod)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeDefinition> enumerator = mod.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					PatchRefsInType(current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public virtual void PatchRefsInType(TypeDefinition type)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_00dc: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			//IL_02da: 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_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Expected O, but got Unknown
			LogVerbose($"[VERBOSE] [PatchRefsInType] Patching refs in {type}");
			if (type.BaseType != null)
			{
				type.BaseType = Extensions.Relink(type.BaseType, new Relinker(Relinker), (IGenericParameterProvider)(object)type);
			}
			for (int i = 0; i < ((TypeReference)type).GenericParameters.Count; i++)
			{
				((TypeReference)type).GenericParameters[i] = Extensions.Relink(((TypeReference)type).GenericParameters[i], new Relinker(Relinker), (IGenericParameterProvider)(object)type);
			}
			for (int j = 0; j < type.Interfaces.Count; j++)
			{
				InterfaceImplementation obj = type.Interfaces[j];
				InterfaceImplementation val = new InterfaceImplementation(Extensions.Relink(obj.InterfaceType, new Relinker(Relinker), (IGenericParameterProvider)(object)type));
				Enumerator<CustomAttribute> enumerator = obj.CustomAttributes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CustomAttribute current = enumerator.Current;
						val.CustomAttributes.Add(Extensions.Relink(current, new Relinker(Relinker), (IGenericParameterProvider)(object)type));
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				type.Interfaces[j] = val;
			}
			for (int k = 0; k < type.CustomAttributes.Count; k++)
			{
				type.CustomAttributes[k] = Extensions.Relink(type.CustomAttributes[k], new Relinker(Relinker), (IGenericParameterProvider)(object)type);
			}
			Enumerator<PropertyDefinition> enumerator2 = type.Properties.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					PropertyDefinition current2 = enumerator2.Current;
					((PropertyReference)current2).PropertyType = Extensions.Relink(((PropertyReference)current2).PropertyType, new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					for (int l = 0; l < current2.CustomAttributes.Count; l++)
					{
						current2.CustomAttributes[l] = Extensions.Relink(current2.CustomAttributes[l], new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Enumerator<EventDefinition> enumerator3 = type.Events.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					EventDefinition current3 = enumerator3.Current;
					((EventReference)current3).EventType = Extensions.Relink(((EventReference)current3).EventType, new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					for (int m = 0; m < current3.CustomAttributes.Count; m++)
					{
						current3.CustomAttributes[m] = Extensions.Relink(current3.CustomAttributes[m], new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Enumerator<MethodDefinition> enumerator4 = type.Methods.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					MethodDefinition current4 = enumerator4.Current;
					PatchRefsInMethod(current4);
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
			Enumerator<FieldDefinition> enumerator5 = type.Fields.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					FieldDefinition current5 = enumerator5.Current;
					((FieldReference)current5).FieldType = Extensions.Relink(((FieldReference)current5).FieldType, new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					for (int n = 0; n < current5.CustomAttributes.Count; n++)
					{
						current5.CustomAttributes[n] = Extensions.Relink(current5.CustomAttributes[n], new Relinker(Relinker), (IGenericParameterProvider)(object)type);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator5).Dispose();
			}
			for (int num = 0; num < type.NestedTypes.Count; num++)
			{
				PatchRefsInType(type.NestedTypes[num]);
			}
		}

		public virtual void PatchRefsInMethod(MethodDefinition method)
		{
			//IL_0030: Unknown result t

BepInEx/patchers/BepInEx.MonoMod.HookGenPatcher/MonoMod.RuntimeDetour.HookGen.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using MonoMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("0x0ade")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2021 0x0ade")]
[assembly: AssemblyDescription("Auto-generate hook helper .dlls, hook arbitrary methods via events: On.Namespace.Type.Method += YourHandlerHere;")]
[assembly: AssemblyFileVersion("21.8.5.1")]
[assembly: AssemblyInformationalVersion("21.08.05.01")]
[assembly: AssemblyProduct("MonoMod.RuntimeDetour.HookGen")]
[assembly: AssemblyTitle("MonoMod.RuntimeDetour.HookGen")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("21.8.5.1")]
[module: UnverifiableCode]
internal static class MultiTargetShims
{
	private static readonly object[] _NoArgs = new object[0];

	public static TypeReference GetConstraintType(this TypeReference type)
	{
		return type;
	}
}
namespace MonoMod
{
	internal static class MMDbgLog
	{
		public static readonly string Tag;

		public static TextWriter Writer;

		public static bool Debugging;

		static MMDbgLog()
		{
			Tag = typeof(MMDbgLog).Assembly.GetName().Name;
			if (Environment.GetEnvironmentVariable("MONOMOD_DBGLOG") == "1" || (Environment.GetEnvironmentVariable("MONOMOD_DBGLOG")?.ToLowerInvariant()?.Contains(Tag.ToLowerInvariant())).GetValueOrDefault())
			{
				Start();
			}
		}

		public static void WaitForDebugger()
		{
			if (!Debugging)
			{
				Debugging = true;
				Debugger.Launch();
				Thread.Sleep(6000);
				Debugger.Break();
			}
		}

		public static void Start()
		{
			if (Writer != null)
			{
				return;
			}
			string text = Environment.GetEnvironmentVariable("MONOMOD_DBGLOG_PATH");
			if (text == "-")
			{
				Writer = Console.Out;
				return;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "mmdbglog.txt";
			}
			text = Path.GetFullPath(Path.GetFileNameWithoutExtension(text) + "-" + Tag + Path.GetExtension(text));
			try
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
			catch
			{
			}
			try
			{
				string directoryName = Path.GetDirectoryName(text);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				Writer = new StreamWriter(new FileStream(text, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete), Encoding.UTF8);
			}
			catch
			{
			}
		}

		public static void Log(string str)
		{
			TextWriter writer = Writer;
			if (writer != null)
			{
				writer.WriteLine(str);
				writer.Flush();
			}
		}

		public static T Log<T>(string str, T value)
		{
			TextWriter writer = Writer;
			if (writer == null)
			{
				return value;
			}
			writer.WriteLine(string.Format(str, value));
			writer.Flush();
			return value;
		}
	}
}
namespace MonoMod.RuntimeDetour.HookGen
{
	public class HookGenerator
	{
		private const string ObsoleteMessageBackCompat = "This method only exists for backwards-compatibility purposes.";

		private static readonly Regex NameVerifyRegex;

		private static readonly Dictionary<Type, string> ReflTypeNameMap;

		private static readonly Dictionary<string, string> TypeNameMap;

		public MonoModder Modder;

		public ModuleDefinition OutputModule;

		public string Namespace;

		public string NamespaceIL;

		public bool HookOrig;

		public bool HookPrivate;

		public string HookExtName;

		public ModuleDefinition module_RuntimeDetour;

		public ModuleDefinition module_Utils;

		public TypeReference t_MulticastDelegate;

		public TypeReference t_IAsyncResult;

		public TypeReference t_AsyncCallback;

		public TypeReference t_MethodBase;

		public TypeReference t_RuntimeMethodHandle;

		public TypeReference t_EditorBrowsableState;

		public MethodReference m_Object_ctor;

		public MethodReference m_ObsoleteAttribute_ctor;

		public MethodReference m_EditorBrowsableAttribute_ctor;

		public MethodReference m_GetMethodFromHandle;

		public MethodReference m_Add;

		public MethodReference m_Remove;

		public MethodReference m_Modify;

		public MethodReference m_Unmodify;

		public TypeReference t_ILManipulator;

		static HookGenerator()
		{
			NameVerifyRegex = new Regex("[^a-zA-Z]");
			ReflTypeNameMap = new Dictionary<Type, string>
			{
				{
					typeof(string),
					"string"
				},
				{
					typeof(object),
					"object"
				},
				{
					typeof(bool),
					"bool"
				},
				{
					typeof(byte),
					"byte"
				},
				{
					typeof(char),
					"char"
				},
				{
					typeof(decimal),
					"decimal"
				},
				{
					typeof(double),
					"double"
				},
				{
					typeof(short),
					"short"
				},
				{
					typeof(int),
					"int"
				},
				{
					typeof(long),
					"long"
				},
				{
					typeof(sbyte),
					"sbyte"
				},
				{
					typeof(float),
					"float"
				},
				{
					typeof(ushort),
					"ushort"
				},
				{
					typeof(uint),
					"uint"
				},
				{
					typeof(ulong),
					"ulong"
				},
				{
					typeof(void),
					"void"
				}
			};
			TypeNameMap = new Dictionary<string, string>();
			foreach (KeyValuePair<Type, string> item in ReflTypeNameMap)
			{
				TypeNameMap[item.Key.FullName] = item.Value;
			}
		}

		public HookGenerator(MonoModder modder, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Expected O, but got Unknown
			//IL_0326: Expected O, but got Unknown
			Modder = modder;
			OutputModule = ModuleDefinition.CreateModule(name, new ModuleParameters
			{
				Architecture = modder.Module.Architecture,
				AssemblyResolver = modder.Module.AssemblyResolver,
				Kind = (ModuleKind)0,
				Runtime = modder.Module.Runtime
			});
			modder.MapDependencies();
			Extensions.AddRange<AssemblyNameReference>(OutputModule.AssemblyReferences, (IEnumerable<AssemblyNameReference>)modder.Module.AssemblyReferences);
			modder.DependencyMap[OutputModule] = new List<ModuleDefinition>(modder.DependencyMap[modder.Module]);
			Namespace = Environment.GetEnvironmentVariable("MONOMOD_HOOKGEN_NAMESPACE");
			if (string.IsNullOrEmpty(Namespace))
			{
				Namespace = "On";
			}
			NamespaceIL = Environment.GetEnvironmentVariable("MONOMOD_HOOKGEN_NAMESPACE_IL");
			if (string.IsNullOrEmpty(NamespaceIL))
			{
				NamespaceIL = "IL";
			}
			HookOrig = Environment.GetEnvironmentVariable("MONOMOD_HOOKGEN_ORIG") == "1";
			HookPrivate = Environment.GetEnvironmentVariable("MONOMOD_HOOKGEN_PRIVATE") == "1";
			modder.MapDependency(modder.Module, "MonoMod.RuntimeDetour", (string)null, (AssemblyNameReference)null);
			if (!modder.DependencyCache.TryGetValue("MonoMod.RuntimeDetour", out module_RuntimeDetour))
			{
				throw new FileNotFoundException("MonoMod.RuntimeDetour not found!");
			}
			modder.MapDependency(modder.Module, "MonoMod.Utils", (string)null, (AssemblyNameReference)null);
			if (!modder.DependencyCache.TryGetValue("MonoMod.Utils", out module_Utils))
			{
				throw new FileNotFoundException("MonoMod.Utils not found!");
			}
			t_MulticastDelegate = OutputModule.ImportReference(modder.FindType("System.MulticastDelegate"));
			t_IAsyncResult = OutputModule.ImportReference(modder.FindType("System.IAsyncResult"));
			t_AsyncCallback = OutputModule.ImportReference(modder.FindType("System.AsyncCallback"));
			t_MethodBase = OutputModule.ImportReference(modder.FindType("System.Reflection.MethodBase"));
			t_RuntimeMethodHandle = OutputModule.ImportReference(modder.FindType("System.RuntimeMethodHandle"));
			t_EditorBrowsableState = OutputModule.ImportReference(modder.FindType("System.ComponentModel.EditorBrowsableState"));
			TypeDefinition type = module_RuntimeDetour.GetType("MonoMod.RuntimeDetour.HookGen.HookEndpointManager");
			t_ILManipulator = OutputModule.ImportReference((TypeReference)(object)module_Utils.GetType("MonoMod.Cil.ILContext/Manipulator"));
			m_Object_ctor = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(modder.FindType("System.Object").Resolve(), "System.Void .ctor()", true));
			m_ObsoleteAttribute_ctor = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(modder.FindType("System.ObsoleteAttribute").Resolve(), "System.Void .ctor(System.String,System.Boolean)", true));
			m_EditorBrowsableAttribute_ctor = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(modder.FindType("System.ComponentModel.EditorBrowsableAttribute").Resolve(), "System.Void .ctor(System.ComponentModel.EditorBrowsableState)", true));
			ModuleDefinition outputModule = OutputModule;
			MethodReference val = new MethodReference("GetMethodFromHandle", t_MethodBase, t_MethodBase);
			val.Parameters.Add(new ParameterDefinition(t_RuntimeMethodHandle));
			m_GetMethodFromHandle = outputModule.ImportReference(val);
			m_Add = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(type, "Add", true));
			m_Remove = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(type, "Remove", true));
			m_Modify = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(type, "Modify", true));
			m_Unmodify = OutputModule.ImportReference((MethodReference)(object)Extensions.FindMethod(type, "Unmodify", true));
		}

		public void Generate()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeDefinition> enumerator = Modder.Module.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					GenerateFor(current, out var hookType, out var hookILType);
					if (hookType != null && hookILType != null && !((TypeReference)hookType).IsNested)
					{
						OutputModule.Types.Add(hookType);
						OutputModule.Types.Add(hookILType);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
		}

		public void GenerateFor(TypeDefinition type, out TypeDefinition hookType, out TypeDefinition hookILType)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			hookType = (hookILType = null);
			if (((TypeReference)type).HasGenericParameters || type.IsRuntimeSpecialName || ((MemberReference)type).Name.StartsWith("<") || (!HookPrivate && type.IsNotPublic))
			{
				return;
			}
			Modder.LogVerbose("[HookGen] Generating for type " + ((MemberReference)type).FullName);
			hookType = new TypeDefinition(((TypeReference)type).IsNested ? null : (Namespace + (string.IsNullOrEmpty(((TypeReference)type).Namespace) ? "" : ("." + ((TypeReference)type).Namespace))), ((MemberReference)type).Name, (TypeAttributes)(((!((TypeReference)type).IsNested) ? 1 : 2) | 0x80 | 0x100 | 0), OutputModule.TypeSystem.Object);
			hookILType = new TypeDefinition(((TypeReference)type).IsNested ? null : (NamespaceIL + (string.IsNullOrEmpty(((TypeReference)type).Namespace) ? "" : ("." + ((TypeReference)type).Namespace))), ((MemberReference)type).Name, (TypeAttributes)(((!((TypeReference)type).IsNested) ? 1 : 2) | 0x80 | 0x100 | 0), OutputModule.TypeSystem.Object);
			bool flag = false;
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					flag |= GenerateFor(hookType, hookILType, current);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<TypeDefinition> enumerator2 = type.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					TypeDefinition current2 = enumerator2.Current;
					GenerateFor(current2, out var hookType2, out var hookILType2);
					if (hookType2 != null && hookILType2 != null)
					{
						flag = true;
						hookType.NestedTypes.Add(hookType2);
						hookILType.NestedTypes.Add(hookILType2);
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			if (!flag)
			{
				hookType = (hookILType = null);
			}
		}

		public bool GenerateFor(TypeDefinition hookType, TypeDefinition hookILType, MethodDefinition method)
		{
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Expected O, but got Unknown
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Expected O, but got Unknown
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Expected O, but got Unknown
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Expected O, but got Unknown
			//IL_03b7: 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_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Expected O, but got Unknown
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Expected O, but got Unknown
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Expected O, but got Unknown
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Expected O, but got Unknown
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Expected O, but got Unknown
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Expected O, but got Unknown
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Expected O, but got Unknown
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Expected O, but got Unknown
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Expected O, but got Unknown
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Expected O, but got Unknown
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0601: Expected O, but got Unknown
			//IL_0610: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Expected O, but got Unknown
			//IL_061e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0628: Expected O, but got Unknown
			//IL_0635: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Expected O, but got Unknown
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Expected O, but got Unknown
			if (((MethodReference)method).HasGenericParameters || method.IsAbstract || (method.IsSpecialName && !method.IsConstructor))
			{
				return false;
			}
			if (!HookOrig && ((MemberReference)method).Name.StartsWith("orig_"))
			{
				return false;
			}
			if (!HookPrivate && method.IsPrivate)
			{
				return false;
			}
			string name = GetFriendlyName((MethodReference)(object)method);
			bool flag = true;
			if (((MethodReference)method).Parameters.Count == 0)
			{
				flag = false;
			}
			IEnumerable<MethodDefinition> source = null;
			if (flag)
			{
				source = ((IEnumerable<MethodDefinition>)method.DeclaringType.Methods).Where((MethodDefinition other) => !((MethodReference)other).HasGenericParameters && GetFriendlyName((MethodReference)(object)other) == name && other != method);
				if (source.Count() == 0)
				{
					flag = false;
				}
			}
			if (flag)
			{
				StringBuilder stringBuilder = new StringBuilder();
				for (int parami = 0; parami < ((MethodReference)method).Parameters.Count; parami++)
				{
					ParameterDefinition param = ((MethodReference)method).Parameters[parami];
					if (!TypeNameMap.TryGetValue(((MemberReference)((ParameterReference)param).ParameterType).FullName, out var typeName))
					{
						typeName = GetFriendlyName(((ParameterReference)param).ParameterType, full: false);
					}
					if (source.Any(delegate(MethodDefinition other)
					{
						ParameterDefinition val11 = ((IEnumerable<ParameterDefinition>)((MethodReference)other).Parameters).ElementAtOrDefault(parami);
						return val11 != null && GetFriendlyName(((ParameterReference)val11).ParameterType, full: false) == typeName && ((ParameterReference)val11).ParameterType.Namespace != ((ParameterReference)param).ParameterType.Namespace;
					}))
					{
						typeName = GetFriendlyName(((ParameterReference)param).ParameterType, full: true);
					}
					stringBuilder.Append("_");
					stringBuilder.Append(typeName.Replace(".", "").Replace("`", ""));
				}
				name += stringBuilder.ToString();
			}
			if (Extensions.FindEvent(hookType, name) != null)
			{
				int num = 1;
				string text;
				while (Extensions.FindEvent(hookType, text = name + "_" + num) != null)
				{
					num++;
				}
				name = text;
			}
			TypeDefinition val = GenerateDelegateFor(method);
			((MemberReference)val).Name = "orig_" + name;
			val.CustomAttributes.Add(GenerateEditorBrowsable(EditorBrowsableState.Never));
			hookType.NestedTypes.Add(val);
			TypeDefinition val2 = GenerateDelegateFor(method);
			((MemberReference)val2).Name = "hook_" + name;
			((MethodReference)Extensions.FindMethod(val2, "Invoke", true)).Parameters.Insert(0, new ParameterDefinition("orig", (ParameterAttributes)0, (TypeReference)(object)val));
			((MethodReference)Extensions.FindMethod(val2, "BeginInvoke", true)).Parameters.Insert(0, new ParameterDefinition("orig", (ParameterAttributes)0, (TypeReference)(object)val));
			val2.CustomAttributes.Add(GenerateEditorBrowsable(EditorBrowsableState.Never));
			hookType.NestedTypes.Add(val2);
			MethodReference val3 = OutputModule.ImportReference((MethodReference)(object)method);
			MethodDefinition val4 = new MethodDefinition("add_" + name, (MethodAttributes)2198, OutputModule.TypeSystem.Void);
			((MethodReference)val4).Parameters.Add(new ParameterDefinition((string)null, (ParameterAttributes)0, (TypeReference)(object)val2));
			val4.Body = new MethodBody(val4);
			ILProcessor iLProcessor = val4.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldtoken, val3);
			iLProcessor.Emit(OpCodes.Call, m_GetMethodFromHandle);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			GenericInstanceMethod val5 = new GenericInstanceMethod(m_Add);
			val5.GenericArguments.Add((TypeReference)(object)val2);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val5);
			iLProcessor.Emit(OpCodes.Ret);
			hookType.Methods.Add(val4);
			MethodDefinition val6 = new MethodDefinition("remove_" + name, (MethodAttributes)2198, OutputModule.TypeSystem.Void);
			((MethodReference)val6).Parameters.Add(new ParameterDefinition((string)null, (ParameterAttributes)0, (TypeReference)(object)val2));
			val6.Body = new MethodBody(val6);
			ILProcessor iLProcessor2 = val6.Body.GetILProcessor();
			iLProcessor2.Emit(OpCodes.Ldtoken, val3);
			iLProcessor2.Emit(OpCodes.Call, m_GetMethodFromHandle);
			iLProcessor2.Emit(OpCodes.Ldarg_0);
			val5 = new GenericInstanceMethod(m_Remove);
			val5.GenericArguments.Add((TypeReference)(object)val2);
			iLProcessor2.Emit(OpCodes.Call, (MethodReference)(object)val5);
			iLProcessor2.Emit(OpCodes.Ret);
			hookType.Methods.Add(val6);
			EventDefinition val7 = new EventDefinition(name, (EventAttributes)0, (TypeReference)(object)val2)
			{
				AddMethod = val4,
				RemoveMethod = val6
			};
			hookType.Events.Add(val7);
			MethodDefinition val8 = new MethodDefinition("add_" + name, (MethodAttributes)2198, OutputModule.TypeSystem.Void);
			((MethodReference)val8).Parameters.Add(new ParameterDefinition((string)null, (ParameterAttributes)0, t_ILManipulator));
			val8.Body = new MethodBody(val8);
			ILProcessor iLProcessor3 = val8.Body.GetILProcessor();
			iLProcessor3.Emit(OpCodes.Ldtoken, val3);
			iLProcessor3.Emit(OpCodes.Call, m_GetMethodFromHandle);
			iLProcessor3.Emit(OpCodes.Ldarg_0);
			val5 = new GenericInstanceMethod(m_Modify);
			val5.GenericArguments.Add((TypeReference)(object)val2);
			iLProcessor3.Emit(OpCodes.Call, (MethodReference)(object)val5);
			iLProcessor3.Emit(OpCodes.Ret);
			hookILType.Methods.Add(val8);
			MethodDefinition val9 = new MethodDefinition("remove_" + name, (MethodAttributes)2198, OutputModule.TypeSystem.Void);
			((MethodReference)val9).Parameters.Add(new ParameterDefinition((string)null, (ParameterAttributes)0, t_ILManipulator));
			val9.Body = new MethodBody(val9);
			ILProcessor iLProcessor4 = val9.Body.GetILProcessor();
			iLProcessor4.Emit(OpCodes.Ldtoken, val3);
			iLProcessor4.Emit(OpCodes.Call, m_GetMethodFromHandle);
			iLProcessor4.Emit(OpCodes.Ldarg_0);
			val5 = new GenericInstanceMethod(m_Unmodify);
			val5.GenericArguments.Add((TypeReference)(object)val2);
			iLProcessor4.Emit(OpCodes.Call, (MethodReference)(object)val5);
			iLProcessor4.Emit(OpCodes.Ret);
			hookILType.Methods.Add(val9);
			EventDefinition val10 = new EventDefinition(name, (EventAttributes)0, t_ILManipulator)
			{
				AddMethod = val8,
				RemoveMethod = val9
			};
			hookILType.Events.Add(val10);
			return true;
		}

		public TypeDefinition GenerateDelegateFor(MethodDefinition method)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: 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_0219: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Expected O, but got Unknown
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Expected O, but got Unknown
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Expected O, but got Unknown
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Expected O, but got Unknown
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Expected O, but got Unknown
			string name = GetFriendlyName((MethodReference)(object)method);
			int num = ((IEnumerable<MethodDefinition>)method.DeclaringType.Methods).Where((MethodDefinition other) => !((MethodReference)other).HasGenericParameters && GetFriendlyName((MethodReference)(object)other) == name).ToList().IndexOf(method);
			if (num != 0)
			{
				string suffix = num.ToString();
				do
				{
					name = name + "_" + suffix;
				}
				while (((IEnumerable<MethodDefinition>)method.DeclaringType.Methods).Any((MethodDefinition other) => !((MethodReference)other).HasGenericParameters && GetFriendlyName((MethodReference)(object)other) == name + suffix));
			}
			name = "d_" + name;
			TypeDefinition val = new TypeDefinition((string)null, (string)null, (TypeAttributes)258, t_MulticastDelegate);
			MethodDefinition val2 = new MethodDefinition(".ctor", (MethodAttributes)6278, OutputModule.TypeSystem.Void)
			{
				ImplAttributes = (MethodImplAttributes)3,
				HasThis = true
			};
			((MethodReference)val2).Parameters.Add(new ParameterDefinition(OutputModule.TypeSystem.Object));
			((MethodReference)val2).Parameters.Add(new ParameterDefinition(OutputModule.TypeSystem.IntPtr));
			val2.Body = new MethodBody(val2);
			val.Methods.Add(val2);
			MethodDefinition val3 = new MethodDefinition("Invoke", (MethodAttributes)454, ImportVisible(((MethodReference)method).ReturnType))
			{
				ImplAttributes = (MethodImplAttributes)3,
				HasThis = true
			};
			if (!method.IsStatic)
			{
				TypeReference val4 = ImportVisible((TypeReference)(object)method.DeclaringType);
				if (((TypeReference)method.DeclaringType).IsValueType)
				{
					val4 = (TypeReference)new ByReferenceType(val4);
				}
				((MethodReference)val3).Parameters.Add(new ParameterDefinition("self", (ParameterAttributes)0, val4));
			}
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					((MethodReference)val3).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, (ParameterAttributes)(current.Attributes & 0xFFEF & 0xEFFF), ImportVisible(((ParameterReference)current).ParameterType)));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			val3.Body = new MethodBody(val3);
			val.Methods.Add(val3);
			MethodDefinition val5 = new MethodDefinition("BeginInvoke", (MethodAttributes)454, t_IAsyncResult)
			{
				ImplAttributes = (MethodImplAttributes)3,
				HasThis = true
			};
			enumerator = ((MethodReference)val3).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current2 = enumerator.Current;
					((MethodReference)val5).Parameters.Add(new ParameterDefinition(((ParameterReference)current2).Name, current2.Attributes, ((ParameterReference)current2).ParameterType));
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			((MethodReference)val5).Parameters.Add(new ParameterDefinition("callback", (ParameterAttributes)0, t_AsyncCallback));
			((MethodReference)val5).Parameters.Add(new ParameterDefinition((string)null, (ParameterAttributes)0, OutputModule.TypeSystem.Object));
			val5.Body = new MethodBody(val5);
			val.Methods.Add(val5);
			MethodDefinition val6 = new MethodDefinition("EndInvoke", (MethodAttributes)454, OutputModule.TypeSystem.Object)
			{
				ImplAttributes = (MethodImplAttributes)3,
				HasThis = true
			};
			((MethodReference)val6).Parameters.Add(new ParameterDefinition("result", (ParameterAttributes)0, t_IAsyncResult));
			val6.Body = new MethodBody(val6);
			val.Methods.Add(val6);
			return val;
		}

		private string GetFriendlyName(MethodReference method)
		{
			string text = ((MemberReference)method).Name;
			if (text.StartsWith("."))
			{
				text = text.Substring(1);
			}
			return text.Replace('.', '_');
		}

		private string GetFriendlyName(TypeReference type, bool full)
		{
			if (type is TypeSpecification)
			{
				StringBuilder stringBuilder = new StringBuilder();
				BuildFriendlyName(stringBuilder, type, full);
				return stringBuilder.ToString();
			}
			if (!full)
			{
				return ((MemberReference)type).Name;
			}
			return ((MemberReference)type).FullName;
		}

		private void BuildFriendlyName(StringBuilder builder, TypeReference type, bool full)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!(type is TypeSpecification))
			{
				builder.Append((full ? ((MemberReference)type).FullName : ((MemberReference)type).Name).Replace("_", ""));
				return;
			}
			if (type.IsByReference)
			{
				builder.Append("ref");
			}
			else if (type.IsPointer)
			{
				builder.Append("ptr");
			}
			BuildFriendlyName(builder, ((TypeSpecification)type).ElementType, full);
			if (type.IsArray)
			{
				builder.Append("Array");
			}
		}

		private bool IsPublic(TypeDefinition typeDef)
		{
			if (typeDef != null && (typeDef.IsNestedPublic || typeDef.IsPublic))
			{
				return !typeDef.IsNotPublic;
			}
			return false;
		}

		private bool HasPublicArgs(GenericInstanceType typeGen)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeReference> enumerator = typeGen.GenericArguments.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeReference current = enumerator.Current;
					if (current.IsGenericParameter)
					{
						return false;
					}
					GenericInstanceType val = (GenericInstanceType)(object)((current is GenericInstanceType) ? current : null);
					if (val != null && !HasPublicArgs(val))
					{
						return false;
					}
					if (!IsPublic(Extensions.SafeResolve(current)))
					{
						return false;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return true;
		}

		private TypeReference ImportVisible(TypeReference typeRef)
		{
			for (TypeDefinition val = ((typeRef != null) ? Extensions.SafeResolve(typeRef) : null); val != null; val = ((typeRef != null) ? Extensions.SafeResolve(typeRef) : null))
			{
				GenericInstanceType val2 = (GenericInstanceType)(object)((typeRef is GenericInstanceType) ? typeRef : null);
				if (val2 == null || HasPublicArgs(val2))
				{
					TypeDefinition val3 = val;
					while (true)
					{
						if (val3 != null)
						{
							if (IsPublic(val3) && (val3 == val || !((TypeReference)val3).HasGenericParameters))
							{
								val3 = val3.DeclaringType;
								continue;
							}
							if (!val.IsEnum)
							{
								break;
							}
							typeRef = ((FieldReference)Extensions.FindField(val, "value__")).FieldType;
						}
						try
						{
							return OutputModule.ImportReference(typeRef);
						}
						catch
						{
							return OutputModule.TypeSystem.Object;
						}
					}
				}
				typeRef = val.BaseType;
			}
			return OutputModule.TypeSystem.Object;
		}

		private CustomAttribute GenerateObsolete(string message, bool error)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			CustomAttribute val = new CustomAttribute(m_ObsoleteAttribute_ctor);
			val.ConstructorArguments.Add(new CustomAttributeArgument(OutputModule.TypeSystem.String, (object)message));
			val.ConstructorArguments.Add(new CustomAttributeArgument(OutputModule.TypeSystem.Boolean, (object)error));
			return val;
		}

		private CustomAttribute GenerateEditorBrowsable(EditorBrowsableState state)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			CustomAttribute val = new CustomAttribute(m_EditorBrowsableAttribute_ctor);
			val.ConstructorArguments.Add(new CustomAttributeArgument(t_EditorBrowsableState, (object)state));
			return val;
		}
	}
	internal class Program
	{
		private static void Main(string[] args)
		{
			//IL_01ec: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			Console.WriteLine("MonoMod.RuntimeDetour.HookGen " + typeof(Program).Assembly.GetName().Version);
			Console.WriteLine("using MonoMod " + typeof(MonoModder).Assembly.GetName().Version);
			Console.WriteLine("using MonoMod.RuntimeDetour " + typeof(Detour).Assembly.GetName().Version);
			if (args.Length == 0)
			{
				Console.WriteLine("No valid arguments (assembly path) passed.");
				if (Debugger.IsAttached)
				{
					Console.ReadKey();
				}
				return;
			}
			int num = 0;
			for (int i = 0; i < args.Length; i++)
			{
				if (args[i] == "--namespace" && i + 2 < args.Length)
				{
					i++;
					Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_NAMESPACE", args[i]);
					continue;
				}
				if (args[i] == "--namespace-il" && i + 2 < args.Length)
				{
					i++;
					Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_NAMESPACE_IL", args[i]);
					continue;
				}
				if (args[i] == "--orig")
				{
					Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_ORIG", "1");
					continue;
				}
				if (args[i] == "--private")
				{
					Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_PRIVATE", "1");
					continue;
				}
				num = i;
				break;
			}
			if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW")))
			{
				Environment.SetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW", "0");
			}
			if (num >= args.Length)
			{
				Console.WriteLine("No assembly path passed.");
				if (Debugger.IsAttached)
				{
					Console.ReadKey();
				}
				return;
			}
			string text = args[num];
			string text2 = ((args.Length != 1 && num != args.Length - 1) ? args[^1] : null);
			text2 = text2 ?? Path.Combine(Path.GetDirectoryName(text), "MMHOOK_" + Path.ChangeExtension(Path.GetFileName(text), "dll"));
			MonoModder val = new MonoModder
			{
				InputPath = text,
				OutputPath = text2,
				ReadingMode = (ReadingMode)2
			};
			try
			{
				val.Read();
				val.MapDependencies();
				if (File.Exists(text2))
				{
					val.Log("[HookGen] Clearing " + text2);
					File.Delete(text2);
				}
				val.Log("[HookGen] Starting HookGenerator");
				HookGenerator hookGenerator = new HookGenerator(val, Path.GetFileName(text2));
				ModuleDefinition outputModule = hookGenerator.OutputModule;
				try
				{
					hookGenerator.Generate();
					outputModule.Write(text2);
				}
				finally
				{
					((IDisposable)outputModule)?.Dispose();
				}
				val.Log("[HookGen] Done.");
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			if (Debugger.IsAttached)
			{
				Console.ReadKey();
			}
		}
	}
}

BepInEx/plugins/BetterLethality.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BetterLethality.Patches;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BetterLethality")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BetterLethality")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e1fe85a1-6433-439e-a3c1-f5d033f179ad")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BetterLethality
{
	[BepInPlugin("vzp.lethality", "Better Lethality", "1.0.0.0")]
	public class LethalityMain : BaseUnityPlugin
	{
		private const string modGUID = "vzp.lethality";

		private const string modName = "Better Lethality";

		private const string modVersion = "1.0.0.0";

		private readonly Harmony harmony = new Harmony("vzp.lethality");

		private static LethalityMain instance;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			harmony.PatchAll(typeof(LethalityMain));
			harmony.PatchAll(typeof(LethalPatch));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Lethality has been bettered");
		}
	}
}
namespace BetterLethality.Patches
{
	[HarmonyPatch(typeof(MenuManager))]
	internal class LethalPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__3_0;

			internal void <AddMods>b__3_0()
			{
				modsPanel.SetActive(true);
			}
		}

		private static GameObject modBtn;

		private static GameObject modsPanel;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void UpdateNews(ref GameObject ___NewsPanel)
		{
			TextMeshProUGUI component = ((Component)((Component)___NewsPanel.transform.Find("Panel")).transform.Find("DemoText")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = ((TMP_Text)component).text + "\n\n[MODS DETECTED]";
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AddMods(ref GameObject ___menuButtons)
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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)
			//IL_0178: Expected O, but got Unknown
			modsPanel = Object.Instantiate<GameObject>(((Component)((Component)___menuButtons.transform.parent).transform.Find("CreditsPanel")).gameObject, ___menuButtons.transform.parent);
			((Object)modsPanel).name = "ModsPanel";
			((TMP_Text)((Component)modsPanel.transform.Find("Panel/NotificationText")).GetComponent<TextMeshProUGUI>()).text = "Installed Mods";
			GameObject val = Object.Instantiate<GameObject>(((Component)modsPanel.transform.Find("Panel/Scroll View/Viewport/Content/CreditsText")).gameObject, modsPanel.transform.Find("Panel/Scroll View/Viewport/Content"));
			((Behaviour)val.GetComponent<TextMeshProUGUI>()).enabled = true;
			Object.Destroy((Object)(object)modsPanel.transform.Find("Panel/Scroll View/Viewport/Content/CreditsText"));
			modBtn = Object.Instantiate<GameObject>(((Component)___menuButtons.transform.Find("HostButton")).gameObject, ___menuButtons.transform);
			((Object)modBtn).name = "ModsButton";
			modBtn.transform.localPosition = new Vector3(-253.6928f, -9.9013f, -5.7486f);
			((TMP_Text)modBtn.GetComponentInChildren<TextMeshProUGUI>()).text = "> Mods";
			((UnityEventBase)modBtn.GetComponent<Button>().onClick).RemoveAllListeners();
			ButtonClickedEvent onClick = modBtn.GetComponent<Button>().onClick;
			object obj = <>c.<>9__3_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					modsPanel.SetActive(true);
				};
				<>c.<>9__3_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			string path = Path.Combine(Directory.GetCurrentDirectory(), "BepInEx/plugins");
			string[] files = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories);
			StringBuilder stringBuilder = new StringBuilder("");
			string[] array = files;
			foreach (string path2 in array)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path2);
				stringBuilder.AppendLine("- " + fileNameWithoutExtension);
			}
			((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = stringBuilder.ToString();
		}
	}
}

BepInEx/plugins/LethalLib/LethalLib.dll

Decompiled 8 months 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.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalLib")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7c7b4f966a6195fee029a3973eece88a0d72f551")]
[assembly: AssemblyProduct("LethalLib")]
[assembly: AssemblyTitle("LethalLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalLib
{
	[BepInPlugin("evaisa.lethallib", "LethalLib", "0.10.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "evaisa.lethallib";

		public const string ModName = "LethalLib";

		public const string ModVersion = "0.10.1";

		public static AssetBundle MainAssets;

		public static ManualLogSource logger;

		public static ConfigFile config;

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			config = ((BaseUnityPlugin)this).Config;
			logger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalLib loaded!!");
			new ILHook((MethodBase)typeof(StackTrace).GetMethod("AddFrames", BindingFlags.Instance | BindingFlags.NonPublic), new Manipulator(IlHook));
			Enemies.Init();
			Items.Init();
			Unlockables.Init();
			MapObjects.Init();
			Dungeon.Init();
			Weathers.Init();
			Player.Init();
			Utilities.Init();
			NetworkPrefabs.Init();
		}

		private void IlHook(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)typeof(StackFrame).GetMethod("GetFileLineNumber", BindingFlags.Instance | BindingFlags.Public))
			});
			val.RemoveRange(2);
			val.EmitDelegate<Func<StackFrame, string>>((Func<StackFrame, string>)GetLineOrIL);
		}

		private static string GetLineOrIL(StackFrame instance)
		{
			int fileLineNumber = instance.GetFileLineNumber();
			if (fileLineNumber == -1 || fileLineNumber == 0)
			{
				return "IL_" + instance.GetILOffset().ToString("X4");
			}
			return fileLineNumber.ToString();
		}
	}
}
namespace LethalLib.Modules
{
	public class ContentLoader
	{
		public class CustomContent
		{
			private string id = "";

			public string ID => id;

			public CustomContent(string id)
			{
				this.id = id;
			}
		}

		public class CustomItem : CustomContent
		{
			public Action<Item> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal Item item;

			public Item Item => item;

			public CustomItem(string id, string contentPath, Action<Item> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
			}
		}

		public class ShopItem : CustomItem
		{
			public int initPrice = 0;

			public string buyNode1Path = null;

			public string buyNode2Path = null;

			public string itemInfoPath = null;

			public void RemoveFromShop()
			{
				Items.RemoveShopItem(base.Item);
			}

			public void SetPrice(int price)
			{
				Items.UpdateShopItemPrice(base.Item, price);
			}

			public ShopItem(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, Action<Item> registryCallback = null)
				: base(id, contentPath, registryCallback)
			{
				initPrice = price;
				this.buyNode1Path = buyNode1Path;
				this.buyNode2Path = buyNode2Path;
				this.itemInfoPath = itemInfoPath;
			}
		}

		public class ScrapItem : CustomItem
		{
			private int rarity = 0;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides = null;

			public int Rarity => rarity;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags)
			{
				Items.RemoveScrapFromLevels(base.Item, levelFlags);
			}

			public ScrapItem(string id, string contentPath, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Action<Item> registryCallback = null)
				: base(id, contentPath, registryCallback)
			{
				this.rarity = rarity;
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
			}
		}

		public class Unlockable : CustomContent
		{
			public Action<UnlockableItem> registryCallback = delegate
			{
			};

			internal UnlockableItem unlockable;

			public string contentPath = "";

			public int initPrice = 0;

			public string buyNode1Path = null;

			public string buyNode2Path = null;

			public string itemInfoPath = null;

			public StoreType storeType = StoreType.None;

			public UnlockableItem UnlockableItem => unlockable;

			public void RemoveFromShop()
			{
				Unlockables.DisableUnlockable(UnlockableItem);
			}

			public void SetPrice(int price)
			{
				Unlockables.UpdateUnlockablePrice(UnlockableItem, price);
			}

			public Unlockable(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, StoreType storeType = StoreType.None, Action<UnlockableItem> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				initPrice = price;
				this.buyNode1Path = buyNode1Path;
				this.buyNode2Path = buyNode2Path;
				this.itemInfoPath = itemInfoPath;
				this.storeType = storeType;
			}
		}

		public class CustomEnemy : CustomContent
		{
			public Action<EnemyType> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal EnemyType enemy;

			public string infoNodePath = null;

			public string infoKeywordPath = null;

			public int rarity = 0;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides = null;

			public Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1);

			public EnemyType Enemy => enemy;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags)
			{
				Enemies.RemoveEnemyFromLevels(Enemy, levelFlags);
			}

			public CustomEnemy(string id, string contentPath, int rarity = 0, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1), string[] levelOverrides = null, string infoNodePath = null, string infoKeywordPath = null, Action<EnemyType> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				this.infoNodePath = infoNodePath;
				this.infoKeywordPath = infoKeywordPath;
				this.rarity = rarity;
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnType = spawnType;
			}
		}

		public class MapHazard : CustomContent
		{
			public Action<SpawnableMapObjectDef> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal SpawnableMapObjectDef hazard;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides = null;

			public SpawnableMapObjectDef Hazard => hazard;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
			{
				MapObjects.RemoveMapObject(Hazard, levelFlags, levelOverrides);
			}

			public MapHazard(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableMapObjectDef> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnRateFunction = spawnRateFunction;
			}
		}

		public class OutsideObject : CustomContent
		{
			public Action<SpawnableOutsideObjectDef> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal SpawnableOutsideObjectDef mapObject;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides = null;

			public SpawnableOutsideObjectDef MapObject => mapObject;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
			{
				MapObjects.RemoveOutsideObject(MapObject, levelFlags, levelOverrides);
			}

			public OutsideObject(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableOutsideObjectDef> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnRateFunction = spawnRateFunction;
			}
		}

		private Dictionary<string, CustomContent> loadedContent = new Dictionary<string, CustomContent>();

		public PluginInfo modInfo;

		private AssetBundle modBundle;

		public Action<CustomContent, GameObject> prefabCallback = delegate
		{
		};

		public Dictionary<string, CustomContent> LoadedContent => loadedContent;

		public string modName => modInfo.Metadata.Name;

		public string modVersion => modInfo.Metadata.Version.ToString();

		public string modGUID => modInfo.Metadata.GUID;

		public ContentLoader(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
		{
			this.modInfo = modInfo;
			this.modBundle = modBundle;
			if (prefabCallback != null)
			{
				this.prefabCallback = prefabCallback;
			}
		}

		public ContentLoader Create(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
		{
			return new ContentLoader(modInfo, modBundle, prefabCallback);
		}

		public void Register(CustomContent content)
		{
			if (loadedContent.ContainsKey(content.ID))
			{
				Debug.LogError((object)("[LethalLib] " + modName + " tried to register content with ID " + content.ID + " but it already exists!"));
				return;
			}
			if (content is CustomItem customItem)
			{
				Item val = (customItem.item = modBundle.LoadAsset<Item>(customItem.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
				Utilities.FixMixerGroups(val.spawnPrefab);
				prefabCallback(content, val.spawnPrefab);
				customItem.registryCallback(val);
				if (content is ShopItem shopItem)
				{
					TerminalNode buyNode = null;
					TerminalNode buyNode2 = null;
					TerminalNode itemInfo = null;
					if (shopItem.buyNode1Path != null)
					{
						buyNode = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode1Path);
					}
					if (shopItem.buyNode2Path != null)
					{
						buyNode2 = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode2Path);
					}
					if (shopItem.itemInfoPath != null)
					{
						itemInfo = modBundle.LoadAsset<TerminalNode>(shopItem.itemInfoPath);
					}
					Items.RegisterShopItem(val, buyNode, buyNode2, itemInfo, shopItem.initPrice);
				}
				else if (content is ScrapItem scrapItem)
				{
					Items.RegisterScrap(val, scrapItem.Rarity, scrapItem.LevelTypes, scrapItem.levelOverrides);
				}
				else
				{
					Items.RegisterItem(val);
				}
			}
			else if (content is Unlockable unlockable)
			{
				UnlockableItemDef unlockableItemDef = modBundle.LoadAsset<UnlockableItemDef>(unlockable.contentPath);
				if ((Object)(object)unlockableItemDef.unlockable.prefabObject != (Object)null)
				{
					NetworkPrefabs.RegisterNetworkPrefab(unlockableItemDef.unlockable.prefabObject);
					prefabCallback(content, unlockableItemDef.unlockable.prefabObject);
					Utilities.FixMixerGroups(unlockableItemDef.unlockable.prefabObject);
				}
				unlockable.unlockable = unlockableItemDef.unlockable;
				unlockable.registryCallback(unlockableItemDef.unlockable);
				TerminalNode buyNode3 = null;
				TerminalNode buyNode4 = null;
				TerminalNode itemInfo2 = null;
				if (unlockable.buyNode1Path != null)
				{
					buyNode3 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode1Path);
				}
				if (unlockable.buyNode2Path != null)
				{
					buyNode4 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode2Path);
				}
				if (unlockable.itemInfoPath != null)
				{
					itemInfo2 = modBundle.LoadAsset<TerminalNode>(unlockable.itemInfoPath);
				}
				Unlockables.RegisterUnlockable(unlockableItemDef, unlockable.storeType, buyNode3, buyNode4, itemInfo2, unlockable.initPrice);
			}
			else if (content is CustomEnemy customEnemy)
			{
				EnemyType val2 = modBundle.LoadAsset<EnemyType>(customEnemy.contentPath);
				NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab);
				Utilities.FixMixerGroups(val2.enemyPrefab);
				customEnemy.enemy = val2;
				prefabCallback(content, val2.enemyPrefab);
				customEnemy.registryCallback(val2);
				TerminalNode infoNode = null;
				TerminalKeyword infoKeyword = null;
				if (customEnemy.infoNodePath != null)
				{
					infoNode = modBundle.LoadAsset<TerminalNode>(customEnemy.infoNodePath);
				}
				if (customEnemy.infoKeywordPath != null)
				{
					infoKeyword = modBundle.LoadAsset<TerminalKeyword>(customEnemy.infoKeywordPath);
				}
				if (customEnemy.spawnType == (Enemies.SpawnType)(-1))
				{
					Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.levelOverrides, infoNode, infoKeyword);
				}
				else
				{
					Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.spawnType, customEnemy.levelOverrides, infoNode, infoKeyword);
				}
			}
			else if (content is MapHazard mapHazard)
			{
				SpawnableMapObjectDef spawnableMapObjectDef = (mapHazard.hazard = modBundle.LoadAsset<SpawnableMapObjectDef>(mapHazard.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				Utilities.FixMixerGroups(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				prefabCallback(content, spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				mapHazard.registryCallback(spawnableMapObjectDef);
				MapObjects.RegisterMapObject(spawnableMapObjectDef, mapHazard.LevelTypes, mapHazard.levelOverrides, mapHazard.spawnRateFunction);
			}
			else if (content is OutsideObject outsideObject)
			{
				SpawnableOutsideObjectDef spawnableOutsideObjectDef = (outsideObject.mapObject = modBundle.LoadAsset<SpawnableOutsideObjectDef>(outsideObject.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				Utilities.FixMixerGroups(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				prefabCallback(content, spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				outsideObject.registryCallback(spawnableOutsideObjectDef);
				MapObjects.RegisterOutsideObject(spawnableOutsideObjectDef, outsideObject.LevelTypes, outsideObject.levelOverrides, outsideObject.spawnRateFunction);
			}
			loadedContent.Add(content.ID, content);
		}

		public void RegisterAll(CustomContent[] content)
		{
			Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Length} content items!");
			foreach (CustomContent content2 in content)
			{
				Register(content2);
			}
		}

		public void RegisterAll(List<CustomContent> content)
		{
			Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Count} content items!");
			foreach (CustomContent item in content)
			{
				Register(item);
			}
		}
	}
	public class Dungeon
	{
		public class CustomDungeonArchetype
		{
			public DungeonArchetype archeType;

			public Levels.LevelTypes LevelTypes;

			public int lineIndex = -1;
		}

		public class CustomGraphLine
		{
			public GraphLine graphLine;

			public Levels.LevelTypes LevelTypes;
		}

		public class CustomDungeon
		{
			public int rarity;

			public DungeonFlow dungeonFlow;

			public Levels.LevelTypes LevelTypes;

			public string[] levelOverrides;

			public int dungeonIndex = -1;

			public AudioClip firstTimeDungeonAudio;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GenerateNewFloor <0>__RoundManager_GenerateNewFloor;

			public static hook_Start <1>__RoundManager_Start;

			public static hook_Start <2>__StartOfRound_Start;
		}

		public static List<CustomDungeonArchetype> customDungeonArchetypes = new List<CustomDungeonArchetype>();

		public static List<CustomGraphLine> customGraphLines = new List<CustomGraphLine>();

		public static Dictionary<string, TileSet> extraTileSets = new Dictionary<string, TileSet>();

		public static Dictionary<string, GameObjectChance> extraRooms = new Dictionary<string, GameObjectChance>();

		public static List<CustomDungeon> customDungeons = new List<CustomDungeon>();

		public static void Init()
		{
			//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_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			//IL_0053: 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_005e: Expected O, but got Unknown
			object obj = <>O.<0>__RoundManager_GenerateNewFloor;
			if (obj == null)
			{
				hook_GenerateNewFloor val = RoundManager_GenerateNewFloor;
				<>O.<0>__RoundManager_GenerateNewFloor = val;
				obj = (object)val;
			}
			RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj;
			object obj2 = <>O.<1>__RoundManager_Start;
			if (obj2 == null)
			{
				hook_Start val2 = RoundManager_Start;
				<>O.<1>__RoundManager_Start = val2;
				obj2 = (object)val2;
			}
			RoundManager.Start += (hook_Start)obj2;
			object obj3 = <>O.<2>__StartOfRound_Start;
			if (obj3 == null)
			{
				hook_Start val3 = StartOfRound_Start;
				<>O.<2>__StartOfRound_Start = val3;
				obj3 = (object)val3;
			}
			StartOfRound.Start += (hook_Start)obj3;
		}

		private static void StartOfRound_Start(orig_Start orig, StartOfRound self)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			foreach (CustomDungeon dungeon in customDungeons)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = dungeon.LevelTypes.HasFlag(Levels.LevelTypes.All) || (dungeon.levelOverrides != null && dungeon.levelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag)
					{
						Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
						if ((flag || dungeon.LevelTypes.HasFlag(levelTypes)) && !val.dungeonFlowTypes.Any((IntWithRarity rarityInt) => rarityInt.id == dungeon.dungeonIndex))
						{
							List<IntWithRarity> list = val.dungeonFlowTypes.ToList();
							list.Add(new IntWithRarity
							{
								id = dungeon.dungeonIndex,
								rarity = dungeon.rarity
							});
							val.dungeonFlowTypes = list.ToArray();
						}
					}
				}
			}
			Plugin.logger.LogInfo((object)"Added custom dungeons to levels");
			orig.Invoke(self);
		}

		private static void RoundManager_Start(orig_Start orig, RoundManager self)
		{
			foreach (CustomDungeon customDungeon in customDungeons)
			{
				if (self.dungeonFlowTypes.Contains(customDungeon.dungeonFlow))
				{
					continue;
				}
				List<DungeonFlow> list = self.dungeonFlowTypes.ToList();
				list.Add(customDungeon.dungeonFlow);
				self.dungeonFlowTypes = list.ToArray();
				int dungeonIndex = self.dungeonFlowTypes.Length - 1;
				customDungeon.dungeonIndex = dungeonIndex;
				List<AudioClip> list2 = self.firstTimeDungeonAudios.ToList();
				if (list2.Count != self.dungeonFlowTypes.Length - 1)
				{
					while (list2.Count < self.dungeonFlowTypes.Length - 1)
					{
						list2.Add(null);
					}
				}
				list2.Add(customDungeon.firstTimeDungeonAudio);
				self.firstTimeDungeonAudios = list2.ToArray();
			}
			orig.Invoke(self);
		}

		private static void RoundManager_GenerateNewFloor(orig_GenerateNewFloor orig, RoundManager self)
		{
			string name = ((Object)self.currentLevel).name;
			if (Enum.IsDefined(typeof(Levels.LevelTypes), name))
			{
				Levels.LevelTypes levelEnum = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name);
				int index = 0;
				self.dungeonGenerator.Generator.DungeonFlow.Lines.ForEach(delegate(GraphLine line)
				{
					foreach (CustomDungeonArchetype customDungeonArchetype in customDungeonArchetypes)
					{
						if (customDungeonArchetype.LevelTypes.HasFlag(levelEnum) && !line.DungeonArchetypes.Contains(customDungeonArchetype.archeType) && (customDungeonArchetype.lineIndex == -1 || customDungeonArchetype.lineIndex == index))
						{
							line.DungeonArchetypes.Add(customDungeonArchetype.archeType);
							Plugin.logger.LogInfo((object)("Added " + ((Object)customDungeonArchetype.archeType).name + " to " + name));
						}
					}
					foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
					{
						string name2 = ((Object)dungeonArchetype).name;
						if (extraTileSets.ContainsKey(name2))
						{
							TileSet val4 = extraTileSets[name2];
							if (!dungeonArchetype.TileSets.Contains(val4))
							{
								dungeonArchetype.TileSets.Add(val4);
								Plugin.logger.LogInfo((object)("Added " + ((Object)val4).name + " to " + name));
							}
						}
						foreach (TileSet tileSet in dungeonArchetype.TileSets)
						{
							string name3 = ((Object)tileSet).name;
							if (extraRooms.ContainsKey(name3))
							{
								GameObjectChance item = extraRooms[name3];
								if (!tileSet.TileWeights.Weights.Contains(item))
								{
									tileSet.TileWeights.Weights.Add(item);
								}
							}
						}
					}
					index++;
				});
				foreach (CustomGraphLine customGraphLine in customGraphLines)
				{
					if (customGraphLine.LevelTypes.HasFlag(levelEnum) && !self.dungeonGenerator.Generator.DungeonFlow.Lines.Contains(customGraphLine.graphLine))
					{
						self.dungeonGenerator.Generator.DungeonFlow.Lines.Add(customGraphLine.graphLine);
					}
				}
			}
			orig.Invoke(self);
			NetworkManager val = Object.FindObjectOfType<NetworkManager>();
			RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
			RandomMapObject[] array2 = array;
			foreach (RandomMapObject val2 in array2)
			{
				for (int j = 0; j < val2.spawnablePrefabs.Count; j++)
				{
					string prefabName = ((Object)val2.spawnablePrefabs[j]).name;
					NetworkPrefab val3 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == prefabName);
					if (val3 != null && (Object)(object)val3.Prefab != (Object)(object)val2.spawnablePrefabs[j])
					{
						val2.spawnablePrefabs[j] = val3.Prefab;
					}
				}
			}
		}

		public static void AddArchetype(DungeonArchetype archetype, Levels.LevelTypes levelFlags, int lineIndex = -1)
		{
			CustomDungeonArchetype customDungeonArchetype = new CustomDungeonArchetype();
			customDungeonArchetype.archeType = archetype;
			customDungeonArchetype.LevelTypes = levelFlags;
			customDungeonArchetype.lineIndex = lineIndex;
			customDungeonArchetypes.Add(customDungeonArchetype);
		}

		public static void AddLine(GraphLine line, Levels.LevelTypes levelFlags)
		{
			CustomGraphLine customGraphLine = new CustomGraphLine();
			customGraphLine.graphLine = line;
			customGraphLine.LevelTypes = levelFlags;
			customGraphLines.Add(customGraphLine);
		}

		public static void AddLine(DungeonGraphLineDef line, Levels.LevelTypes levelFlags)
		{
			AddLine(line.graphLine, levelFlags);
		}

		public static void AddTileSet(TileSet set, string archetypeName)
		{
			extraTileSets.Add(archetypeName, set);
		}

		public static void AddRoom(GameObjectChance room, string tileSetName)
		{
			extraRooms.Add(tileSetName, room);
		}

		public static void AddRoom(GameObjectChanceDef room, string tileSetName)
		{
			AddRoom(room.gameObjectChance, tileSetName);
		}

		public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags)
		{
			AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, dungeon.firstTimeDungeonAudio);
		}

		public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags, string[] levelOverrides)
		{
			AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, levelOverrides, dungeon.firstTimeDungeonAudio);
		}

		public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, AudioClip firstTimeDungeonAudio = null)
		{
			customDungeons.Add(new CustomDungeon
			{
				dungeonFlow = dungeon,
				rarity = rarity,
				LevelTypes = levelFlags,
				firstTimeDungeonAudio = firstTimeDungeonAudio
			});
		}

		public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, string[] levelOverrides = null, AudioClip firstTimeDungeonAudio = null)
		{
			customDungeons.Add(new CustomDungeon
			{
				dungeonFlow = dungeon,
				rarity = rarity,
				LevelTypes = levelFlags,
				firstTimeDungeonAudio = firstTimeDungeonAudio,
				levelOverrides = levelOverrides
			});
		}
	}
	public class Enemies
	{
		public struct EnemyAssetInfo
		{
			public EnemyType EnemyAsset;

			public TerminalKeyword keyword;
		}

		public enum SpawnType
		{
			Default,
			Daytime,
			Outside
		}

		public class SpawnableEnemy
		{
			public EnemyType enemy;

			public int rarity;

			public Levels.LevelTypes spawnLevels;

			public SpawnType spawnType;

			public TerminalNode terminalNode;

			public TerminalKeyword infoKeyword;

			public string modName;

			public string[] spawnLevelOverrides;

			public SpawnableEnemy(EnemyType enemy, int rarity, Levels.LevelTypes spawnLevels, SpawnType spawnType, string[] spawnLevelOverrides = null)
			{
				this.enemy = enemy;
				this.rarity = rarity;
				this.spawnLevels = spawnLevels;
				this.spawnType = spawnType;
				this.spawnLevelOverrides = spawnLevelOverrides;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__RegisterLevelEnemies;

			public static hook_Start <1>__Terminal_Start;
		}

		public static Terminal terminal;

		public static List<EnemyAssetInfo> enemyAssetInfos = new List<EnemyAssetInfo>();

		public static List<SpawnableEnemy> spawnableEnemies = new List<SpawnableEnemy>();

		public static void Init()
		{
			//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_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			object obj = <>O.<0>__RegisterLevelEnemies;
			if (obj == null)
			{
				hook_Awake val = RegisterLevelEnemies;
				<>O.<0>__RegisterLevelEnemies = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__Terminal_Start;
			if (obj2 == null)
			{
				hook_Start val2 = Terminal_Start;
				<>O.<1>__Terminal_Start = val2;
				obj2 = (object)val2;
			}
			Terminal.Start += (hook_Start)obj2;
		}

		private static void Terminal_Start(orig_Start orig, Terminal self)
		{
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			terminal = self;
			TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			List<string> list = new List<string>();
			foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
			{
				if (list.Contains(spawnableEnemy.enemy.enemyName))
				{
					Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
					continue;
				}
				if ((Object)(object)spawnableEnemy.terminalNode == (Object)null)
				{
					spawnableEnemy.terminalNode = ScriptableObject.CreateInstance<TerminalNode>();
					spawnableEnemy.terminalNode.displayText = spawnableEnemy.enemy.enemyName + "\n\nDanger level: Unknown\n\n[No information about this creature was found.]\n\n";
					spawnableEnemy.terminalNode.clearPreviousText = true;
					spawnableEnemy.terminalNode.maxCharactersToType = 35;
					spawnableEnemy.terminalNode.creatureName = spawnableEnemy.enemy.enemyName;
				}
				if (self.enemyFiles.Any((TerminalNode x) => x.creatureName == spawnableEnemy.terminalNode.creatureName))
				{
					Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
					continue;
				}
				TerminalKeyword keyword2 = (((Object)(object)spawnableEnemy.infoKeyword != (Object)null) ? spawnableEnemy.infoKeyword : TerminalUtils.CreateTerminalKeyword(spawnableEnemy.terminalNode.creatureName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val));
				keyword2.defaultVerb = val;
				List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
				if (!list2.Any((TerminalKeyword x) => x.word == keyword2.word))
				{
					list2.Add(keyword2);
					self.terminalNodes.allKeywords = list2.ToArray();
				}
				List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
				if (!list3.Any((CompatibleNoun x) => x.noun.word == keyword2.word))
				{
					list3.Add(new CompatibleNoun
					{
						noun = keyword2,
						result = spawnableEnemy.terminalNode
					});
				}
				val.compatibleNouns = list3.ToArray();
				spawnableEnemy.terminalNode.creatureFileID = self.enemyFiles.Count;
				self.enemyFiles.Add(spawnableEnemy.terminalNode);
				spawnableEnemy.enemy.enemyPrefab.GetComponentInChildren<ScanNodeProperties>().creatureScanID = spawnableEnemy.terminalNode.creatureFileID;
				EnemyAssetInfo enemyAssetInfo = default(EnemyAssetInfo);
				enemyAssetInfo.EnemyAsset = spawnableEnemy.enemy;
				enemyAssetInfo.keyword = keyword2;
				EnemyAssetInfo item = enemyAssetInfo;
				enemyAssetInfos.Add(item);
			}
			orig.Invoke(self);
		}

		private static void RegisterLevelEnemies(orig_Awake orig, StartOfRound self)
		{
			//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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			orig.Invoke(self);
			foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = spawnableEnemy.spawnLevels.HasFlag(Levels.LevelTypes.All) || (spawnableEnemy.spawnLevelOverrides != null && spawnableEnemy.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
					{
						continue;
					}
					Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
					if (!flag && !spawnableEnemy.spawnLevels.HasFlag(levelTypes))
					{
						continue;
					}
					SpawnableEnemyWithRarity item2 = new SpawnableEnemyWithRarity
					{
						enemyType = spawnableEnemy.enemy,
						rarity = spawnableEnemy.rarity
					};
					switch (spawnableEnemy.spawnType)
					{
					case SpawnType.Default:
						if (!val.Enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
						{
							val.Enemies.Add(item2);
							Plugin.logger.LogInfo((object)("Added " + ((Object)spawnableEnemy.enemy).name + " to " + name + " with SpawnType [Default]"));
						}
						break;
					case SpawnType.Daytime:
						if (!val.DaytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
						{
							val.DaytimeEnemies.Add(item2);
							Plugin.logger.LogInfo((object)("Added " + ((Object)spawnableEnemy.enemy).name + " to " + name + " with SpawnType [Daytime]"));
						}
						break;
					case SpawnType.Outside:
						if (!val.OutsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
						{
							val.OutsideEnemies.Add(item2);
							Plugin.logger.LogInfo((object)("Added " + ((Object)spawnableEnemy.enemy).name + " to " + name + " with SpawnType [Outside]"));
						}
						break;
					}
				}
			}
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			SpawnableEnemy spawnableEnemy = new SpawnableEnemy(enemy, rarity, levelFlags, spawnType);
			spawnableEnemy.terminalNode = infoNode;
			spawnableEnemy.infoKeyword = infoKeyword;
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			spawnableEnemy.modName = name;
			spawnableEnemies.Add(spawnableEnemy);
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			SpawnableEnemy spawnableEnemy = new SpawnableEnemy(enemy, rarity, levelFlags, spawnType, spawnLevelOverrides);
			spawnableEnemy.terminalNode = infoNode;
			spawnableEnemy.infoKeyword = infoKeyword;
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			spawnableEnemy.modName = name;
			spawnableEnemies.Add(spawnableEnemy);
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			SpawnableEnemy spawnableEnemy = new SpawnableEnemy(enemy, rarity, levelFlags, enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
			spawnableEnemy.terminalNode = infoNode;
			spawnableEnemy.infoKeyword = infoKeyword;
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			spawnableEnemy.modName = name;
			spawnableEnemies.Add(spawnableEnemy);
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			SpawnableEnemy spawnableEnemy = new SpawnableEnemy(enemy, rarity, levelFlags, enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default), spawnLevelOverrides);
			spawnableEnemy.terminalNode = infoNode;
			spawnableEnemy.infoKeyword = infoKeyword;
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			spawnableEnemy.modName = name;
			spawnableEnemies.Add(spawnableEnemy);
		}

		public static void RemoveEnemyFromLevels(EnemyType enemyType, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					List<SpawnableEnemyWithRarity> enemies = val.Enemies;
					List<SpawnableEnemyWithRarity> daytimeEnemies = val.DaytimeEnemies;
					List<SpawnableEnemyWithRarity> outsideEnemies = val.OutsideEnemies;
					enemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType);
					daytimeEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType);
					outsideEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType);
				}
			}
		}
	}
	public class Items
	{
		public struct ItemSaveOrderData
		{
			public int itemId;

			public string itemName;

			public string assetName;
		}

		public struct BuyableItemAssetInfo
		{
			public Item itemAsset;

			public TerminalKeyword keyword;
		}

		public class ScrapItem
		{
			public Item item;

			public int rarity;

			public Levels.LevelTypes spawnLevels;

			public string[] spawnLevelOverrides;

			public string modName;

			public ScrapItem(Item item, int rarity, Levels.LevelTypes spawnLevels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null)
			{
				this.item = item;
				this.rarity = rarity;
				this.spawnLevels = spawnLevels;
				this.spawnLevelOverrides = spawnLevelOverrides;
			}
		}

		public class PlainItem
		{
			public Item item;

			public string modName;

			public PlainItem(Item item)
			{
				this.item = item;
			}
		}

		public class ShopItem
		{
			public Item item;

			public TerminalNode buyNode1;

			public TerminalNode buyNode2;

			public TerminalNode itemInfo;

			public int price;

			public string modName;

			public ShopItem(Item item, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0)
			{
				this.item = item;
				this.price = price;
				if ((Object)(object)buyNode1 != (Object)null)
				{
					this.buyNode1 = buyNode1;
				}
				if ((Object)(object)buyNode2 != (Object)null)
				{
					this.buyNode2 = buyNode2;
				}
				if ((Object)(object)itemInfo != (Object)null)
				{
					this.itemInfo = itemInfo;
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;

			public static hook_Start <1>__StartOfRound_Start;

			public static hook_Awake <2>__Terminal_Awake;
		}

		public static ConfigEntry<bool> useSavedataFix;

		public static List<Item> LethalLibItemList = new List<Item>();

		public static List<BuyableItemAssetInfo> buyableItemAssetInfos = new List<BuyableItemAssetInfo>();

		public static Terminal terminal;

		public static List<ScrapItem> scrapItems = new List<ScrapItem>();

		public static List<ShopItem> shopItems = new List<ShopItem>();

		public static List<PlainItem> plainItems = new List<PlainItem>();

		public static void Init()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			useSavedataFix = Plugin.config.Bind<bool>("Items", "EnableItemSaveFix", false, "Allow for LethalLib to store/reorder the item list, which should fix issues where items get reshuffled when loading an old save. This is experimental and may cause save corruptions occasionally.");
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__StartOfRound_Start;
			if (obj2 == null)
			{
				hook_Start val2 = StartOfRound_Start;
				<>O.<1>__StartOfRound_Start = val2;
				obj2 = (object)val2;
			}
			StartOfRound.Start += (hook_Start)obj2;
			object obj3 = <>O.<2>__Terminal_Awake;
			if (obj3 == null)
			{
				hook_Awake val3 = Terminal_Awake;
				<>O.<2>__Terminal_Awake = val3;
				obj3 = (object)val3;
			}
			Terminal.Awake += (hook_Awake)obj3;
		}

		private static void StartOfRound_Start(orig_Start orig, StartOfRound self)
		{
			if (useSavedataFix.Value && ((NetworkBehaviour)self).IsHost)
			{
				Plugin.logger.LogInfo((object)"Fixing Item savedata!!");
				List<ItemSaveOrderData> itemList = new List<ItemSaveOrderData>();
				StartOfRound.Instance.allItemsList.itemsList.ForEach(delegate(Item item)
				{
					itemList.Add(new ItemSaveOrderData
					{
						itemId = item.itemId,
						itemName = item.itemName,
						assetName = ((Object)item).name
					});
				});
				if (ES3.KeyExists("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName))
				{
					itemList = ES3.Load<List<ItemSaveOrderData>>("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName);
				}
				List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
				List<Item> list = new List<Item>();
				foreach (ItemSaveOrderData item2 in itemList)
				{
					Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => x.itemId == item2.itemId && x.itemName == item2.itemName && item2.assetName == ((Object)x).name));
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
					else
					{
						list.Add(ScriptableObject.CreateInstance<Item>());
					}
				}
				foreach (Item item3 in itemsList)
				{
					if (!list.Contains(item3))
					{
						list.Add(item3);
					}
				}
				StartOfRound.Instance.allItemsList.itemsList = list;
				ES3.Save<List<ItemSaveOrderData>>("LethalLibAllItemsList", itemList, GameNetworkManager.Instance.currentSaveFileName);
			}
			orig.Invoke(self);
		}

		private static void Terminal_Awake(orig_Awake orig, Terminal self)
		{
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Expected O, but got Unknown
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Expected O, but got Unknown
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Expected O, but got Unknown
			terminal = self;
			List<Item> list = self.buyableItemsList.ToList();
			TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
			TerminalKeyword val2 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			Plugin.logger.LogInfo((object)$"Adding {shopItems.Count} items to terminal");
			foreach (ShopItem item in shopItems)
			{
				if (list.Any((Item x) => x.itemName == item.item.itemName))
				{
					Plugin.logger.LogInfo((object)("Item " + item.item.itemName + " already exists in terminal, skipping"));
					continue;
				}
				if (item.price == -1)
				{
					item.price = item.item.creditsWorth;
				}
				else
				{
					item.item.creditsWorth = item.price;
				}
				list.Add(item.item);
				string itemName = item.item.itemName;
				char c = itemName[itemName.Length - 1];
				string text = itemName;
				TerminalNode val3 = item.buyNode2;
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val3).name = itemName.Replace(" ", "-") + "BuyNode2";
					val3.displayText = "Ordered [variableAmount] " + text + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n";
					val3.clearPreviousText = true;
					val3.maxCharactersToType = 15;
				}
				val3.buyItemIndex = list.Count - 1;
				val3.isConfirmationNode = false;
				val3.itemCost = item.price;
				val3.playSyncedClip = 0;
				TerminalNode val4 = item.buyNode1;
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val4).name = itemName.Replace(" ", "-") + "BuyNode1";
					val4.displayText = "You have requested to order " + text + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n";
					val4.clearPreviousText = true;
					val4.maxCharactersToType = 35;
				}
				val4.buyItemIndex = list.Count - 1;
				val4.isConfirmationNode = true;
				val4.overrideOptions = true;
				val4.itemCost = item.price;
				val4.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
				{
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "confirm"),
						result = val3
					},
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "deny"),
						result = result
					}
				};
				TerminalKeyword val5 = TerminalUtils.CreateTerminalKeyword(itemName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val);
				List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
				list2.Add(val5);
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
				list3.Add(new CompatibleNoun
				{
					noun = val5,
					result = val4
				});
				val.compatibleNouns = list3.ToArray();
				TerminalNode val6 = item.itemInfo;
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val6).name = itemName.Replace(" ", "-") + "InfoNode";
					val6.displayText = "[No information about this object was found.]\n\n";
					val6.clearPreviousText = true;
					val6.maxCharactersToType = 25;
				}
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list4 = val2.compatibleNouns.ToList();
				list4.Add(new CompatibleNoun
				{
					noun = val5,
					result = val6
				});
				val2.compatibleNouns = list4.ToArray();
				BuyableItemAssetInfo buyableItemAssetInfo = default(BuyableItemAssetInfo);
				buyableItemAssetInfo.itemAsset = item.item;
				buyableItemAssetInfo.keyword = val5;
				BuyableItemAssetInfo item2 = buyableItemAssetInfo;
				buyableItemAssetInfos.Add(item2);
			}
			self.buyableItemsList = list.ToArray();
			orig.Invoke(self);
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			orig.Invoke(self);
			foreach (ScrapItem scrapItem in scrapItems)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = scrapItem.spawnLevels.HasFlag(Levels.LevelTypes.All) || (scrapItem.spawnLevelOverrides != null && scrapItem.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
					{
						continue;
					}
					Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
					if (flag || scrapItem.spawnLevels.HasFlag(levelTypes))
					{
						SpawnableItemWithRarity item2 = new SpawnableItemWithRarity
						{
							spawnableItem = scrapItem.item,
							rarity = scrapItem.rarity
						};
						if (!val.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem.item))
						{
							val.spawnableScrap.Add(item2);
						}
					}
				}
			}
			foreach (ScrapItem scrapItem2 in scrapItems)
			{
				if (!self.allItemsList.itemsList.Contains(scrapItem2.item))
				{
					if (scrapItem2.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(scrapItem2.modName + " registered item: " + scrapItem2.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered item: " + scrapItem2.item.itemName));
					}
					LethalLibItemList.Add(scrapItem2.item);
					self.allItemsList.itemsList.Add(scrapItem2.item);
				}
			}
			foreach (ShopItem shopItem in shopItems)
			{
				if (!self.allItemsList.itemsList.Contains(shopItem.item))
				{
					if (shopItem.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(shopItem.modName + " registered item: " + shopItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered item: " + shopItem.item.itemName));
					}
					LethalLibItemList.Add(shopItem.item);
					self.allItemsList.itemsList.Add(shopItem.item);
				}
			}
			foreach (PlainItem plainItem in plainItems)
			{
				if (!self.allItemsList.itemsList.Contains(plainItem.item))
				{
					if (plainItem.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(plainItem.modName + " registered item: " + plainItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered item: " + plainItem.item.itemName));
					}
					LethalLibItemList.Add(plainItem.item);
					self.allItemsList.itemsList.Add(plainItem.item);
				}
			}
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags)
		{
			ScrapItem scrapItem = new ScrapItem(spawnableItem, rarity, levelFlags);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			scrapItem.modName = name;
			scrapItems.Add(scrapItem);
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			ScrapItem scrapItem = new ScrapItem(spawnableItem, rarity, levelFlags, levelOverrides);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			scrapItem.modName = name;
			scrapItems.Add(scrapItem);
		}

		public static void RegisterShopItem(Item shopItem, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
		{
			ShopItem shopItem2 = new ShopItem(shopItem, buyNode1, buyNode2, itemInfo, price);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			shopItem2.modName = name;
			shopItems.Add(shopItem2);
		}

		public static void RegisterShopItem(Item shopItem, int price = -1)
		{
			ShopItem shopItem2 = new ShopItem(shopItem, null, null, null, price);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			shopItem2.modName = name;
			shopItems.Add(shopItem2);
		}

		public static void RegisterItem(Item plainItem)
		{
			PlainItem plainItem2 = new PlainItem(plainItem);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			plainItem2.modName = name;
			plainItems.Add(plainItem2);
		}

		public static void RemoveScrapFromLevels(Item scrapItem, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					SpawnableItemWithRarity val2 = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem));
					if (val2 != null)
					{
						val.spawnableScrap.Remove(val2);
					}
				}
			}
		}

		public static void RemoveShopItem(Item shopItem)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			List<Item> list = terminal.buyableItemsList.ToList();
			list.RemoveAll((Item x) => (Object)(object)x == (Object)(object)shopItem);
			terminal.buyableItemsList = list.ToArray();
			List<TerminalKeyword> list2 = terminal.terminalNodes.allKeywords.ToList();
			TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			TerminalKeyword val2 = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			List<CompatibleNoun> list3 = val2.compatibleNouns.ToList();
			List<CompatibleNoun> list4 = val.compatibleNouns.ToList();
			if (buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)shopItem))
			{
				BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)shopItem);
				list2.Remove(asset.keyword);
				list3.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
				list4.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
			}
			terminal.terminalNodes.allKeywords = list2.ToArray();
			val2.compatibleNouns = list3.ToArray();
			val.compatibleNouns = list4.ToArray();
		}

		public static void UpdateShopItemPrice(Item shopItem, int price)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			shopItem.creditsWorth = price;
			TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
			List<CompatibleNoun> source = val.compatibleNouns.ToList();
			if (!buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)shopItem))
			{
				return;
			}
			BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)shopItem);
			if (!source.Any((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword))
			{
				return;
			}
			CompatibleNoun val2 = source.First((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
			TerminalNode result2 = val2.result;
			result2.itemCost = price;
			if (result2.terminalOptions.Length == 0)
			{
				return;
			}
			CompatibleNoun[] terminalOptions = result2.terminalOptions;
			foreach (CompatibleNoun val3 in terminalOptions)
			{
				if ((Object)(object)val3.result != (Object)null && val3.result.buyItemIndex != -1)
				{
					val3.result.itemCost = price;
				}
			}
		}
	}
	public class Levels
	{
		[Flags]
		public enum LevelTypes
		{
			None = 1,
			ExperimentationLevel = 4,
			AssuranceLevel = 8,
			VowLevel = 0x10,
			OffenseLevel = 0x20,
			MarchLevel = 0x40,
			RendLevel = 0x80,
			DineLevel = 0x100,
			TitanLevel = 0x200,
			Vanilla = 0x3FC,
			All = -1
		}
	}
	public class MapObjects
	{
		public class RegisteredMapObject
		{
			public SpawnableMapObject mapObject;

			public SpawnableOutsideObjectWithRarity outsideObject;

			public Levels.LevelTypes levels;

			public string[] spawnLevelOverrides;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;

			public static hook_SpawnMapObjects <1>__RoundManager_SpawnMapObjects;
		}

		public static List<RegisteredMapObject> mapObjects = new List<RegisteredMapObject>();

		public static void Init()
		{
			//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_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__RoundManager_SpawnMapObjects;
			if (obj2 == null)
			{
				hook_SpawnMapObjects val2 = RoundManager_SpawnMapObjects;
				<>O.<1>__RoundManager_SpawnMapObjects = val2;
				obj2 = (object)val2;
			}
			RoundManager.SpawnMapObjects += (hook_SpawnMapObjects)obj2;
		}

		private static void RoundManager_SpawnMapObjects(orig_SpawnMapObjects orig, RoundManager self)
		{
			RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
			RandomMapObject[] array2 = array;
			foreach (RandomMapObject val in array2)
			{
				foreach (RegisteredMapObject mapObject in mapObjects)
				{
					if (mapObject.mapObject != null && !val.spawnablePrefabs.Any((GameObject prefab) => (Object)(object)prefab == (Object)(object)mapObject.mapObject.prefabToSpawn))
					{
						val.spawnablePrefabs.Add(mapObject.mapObject.prefabToSpawn);
					}
				}
			}
			orig.Invoke(self);
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			orig.Invoke(self);
			foreach (RegisteredMapObject mapObject in mapObjects)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = mapObject.levels.HasFlag(Levels.LevelTypes.All) || (mapObject.spawnLevelOverrides != null && mapObject.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
					{
						continue;
					}
					Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
					if (!flag && !mapObject.levels.HasFlag(levelTypes))
					{
						continue;
					}
					if (mapObject.mapObject != null)
					{
						if (!val.spawnableMapObjects.Any((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn))
						{
							List<SpawnableMapObject> list = val.spawnableMapObjects.ToList();
							list.RemoveAll((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn);
							val.spawnableMapObjects = list.ToArray();
						}
						SpawnableMapObject mapObject2 = mapObject.mapObject;
						if (mapObject.spawnRateFunction != null)
						{
							mapObject2.numberToSpawn = mapObject.spawnRateFunction(val);
						}
						List<SpawnableMapObject> list2 = val.spawnableMapObjects.ToList();
						list2.Add(mapObject2);
						val.spawnableMapObjects = list2.ToArray();
						Plugin.logger.LogInfo((object)("Added " + ((Object)mapObject2.prefabToSpawn).name + " to " + name));
					}
					else
					{
						if (mapObject.outsideObject == null)
						{
							continue;
						}
						if (!val.spawnableOutsideObjects.Any((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn))
						{
							List<SpawnableOutsideObjectWithRarity> list3 = val.spawnableOutsideObjects.ToList();
							list3.RemoveAll((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn);
							val.spawnableOutsideObjects = list3.ToArray();
						}
						SpawnableOutsideObjectWithRarity outsideObject = mapObject.outsideObject;
						if (mapObject.spawnRateFunction != null)
						{
							outsideObject.randomAmount = mapObject.spawnRateFunction(val);
						}
						List<SpawnableOutsideObjectWithRarity> list4 = val.spawnableOutsideObjects.ToList();
						list4.Add(outsideObject);
						val.spawnableOutsideObjects = list4.ToArray();
						Plugin.logger.LogInfo((object)("Added " + ((Object)outsideObject.spawnableObject.prefabToSpawn).name + " to " + name));
					}
				}
			}
		}

		public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterMapObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
		}

		public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterMapObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
		}

		public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				mapObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction
			});
		}

		public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				mapObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction,
				spawnLevelOverrides = levelOverrides
			});
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterOutsideObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterOutsideObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				outsideObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction
			});
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				outsideObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction,
				spawnLevelOverrides = levelOverrides
			});
		}

		public static void RemoveMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			RemoveMapObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
		}

		public static void RemoveMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					val.spawnableMapObjects = val.spawnableMapObjects.Where((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn != (Object)(object)mapObject.prefabToSpawn).ToArray();
				}
			}
		}

		public static void RemoveOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			RemoveOutsideObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
		}

		public static void RemoveOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					val.spawnableOutsideObjects = val.spawnableOutsideObjects.Where((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn != (Object)(object)mapObject.spawnableObject.prefabToSpawn).ToArray();
				}
			}
		}
	}
	public class NetworkPrefabs
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__GameNetworkManager_Start;
		}

		private static List<GameObject> _networkPrefabs = new List<GameObject>();

		internal static void Init()
		{
			//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_001c: Expected O, but got Unknown
			object obj = <>O.<0>__GameNetworkManager_Start;
			if (obj == null)
			{
				hook_Start val = GameNetworkManager_Start;
				<>O.<0>__GameNetworkManager_Start = val;
				obj = (object)val;
			}
			GameNetworkManager.Start += (hook_Start)obj;
		}

		public static void RegisterNetworkPrefab(GameObject prefab)
		{
			_networkPrefabs.Add(prefab);
		}

		private static void GameNetworkManager_Start(orig_Start orig, GameNetworkManager self)
		{
			orig.Invoke(self);
			foreach (GameObject networkPrefab in _networkPrefabs)
			{
				((Component)self).GetComponent<NetworkManager>().AddNetworkPrefab(networkPrefab);
			}
		}
	}
	public class Player
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;
		}

		public static Dictionary<string, GameObject> ragdollRefs = new Dictionary<string, GameObject>();

		public static Dictionary<string, int> ragdollIndexes = new Dictionary<string, int>();

		public static void Init()
		{
			//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_001c: Expected O, but got Unknown
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			orig.Invoke(self);
			foreach (KeyValuePair<string, GameObject> ragdollRef in ragdollRefs)
			{
				if (!self.playerRagdolls.Contains(ragdollRef.Value))
				{
					self.playerRagdolls.Add(ragdollRef.Value);
					int value = self.playerRagdolls.Count - 1;
					if (ragdollIndexes.ContainsKey(ragdollRef.Key))
					{
						ragdollIndexes[ragdollRef.Key] = value;
					}
					else
					{
						ragdollIndexes.Add(ragdollRef.Key, value);
					}
				}
			}
		}

		public static int GetRagdollIndex(string id)
		{
			return ragdollIndexes[id];
		}

		public static GameObject GetRagdoll(string id)
		{
			return ragdollRefs[id];
		}

		public static void RegisterPlayerRagdoll(string id, GameObject ragdoll)
		{
			Plugin.logger.LogInfo((object)("Registering player ragdoll " + id));
			ragdollRefs.Add(id, ragdoll);
		}
	}
	public class Shaders
	{
		public static void FixShaders(GameObject gameObject)
		{
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if (((Object)val2.shader).name.Contains("Standard"))
					{
						val2.shader = Shader.Find("HDRP/Lit");
					}
				}
			}
		}
	}
	public class TerminalUtils
	{
		public static TerminalKeyword CreateTerminalKeyword(string word, bool isVerb = false, CompatibleNoun[] compatibleNouns = null, TerminalNode specialKeywordResult = null, TerminalKeyword defaultVerb = null, bool accessTerminalObjects = false)
		{
			TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val).name = word;
			val.word = word;
			val.isVerb = isVerb;
			val.compatibleNouns = compatibleNouns;
			val.specialKeywordResult = specialKeywordResult;
			val.defaultVerb = defaultVerb;
			val.accessTerminalObjects = accessTerminalObjects;
			return val;
		}
	}
	public enum StoreType
	{
		None,
		ShipUpgrade,
		Decor
	}
	public class Unlockables
	{
		public class RegisteredUnlockable
		{
			public UnlockableItem unlockable;

			public StoreType StoreType;

			public TerminalNode buyNode1;

			public TerminalNode buyNode2;

			public TerminalNode itemInfo;

			public int price;

			public string modName;

			public bool disabled = false;

			public RegisteredUnlockable(UnlockableItem unlockable, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
			{
				this.unlockable = unlockable;
				this.buyNode1 = buyNode1;
				this.buyNode2 = buyNode2;
				this.itemInfo = itemInfo;
				this.price = price;
			}
		}

		public struct BuyableUnlockableAssetInfo
		{
			public UnlockableItem itemAsset;

			public TerminalKeyword keyword;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;

			public static hook_Start <1>__Terminal_Start;

			public static hook_TextPostProcess <2>__Terminal_TextPostProcess;
		}

		public static List<RegisteredUnlockable> registeredUnlockables = new List<RegisteredUnlockable>();

		public static List<BuyableUnlockableAssetInfo> buyableUnlockableAssetInfos = new List<BuyableUnlockableAssetInfo>();

		public static void Init()
		{
			//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_001c: Expected O, but got Unknown
			//IL_0032: 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_003d: Expected O, but got Unknown
			//IL_0053: 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_005e: Expected O, but got Unknown
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__Terminal_Start;
			if (obj2 == null)
			{
				hook_Start val2 = Terminal_Start;
				<>O.<1>__Terminal_Start = val2;
				obj2 = (object)val2;
			}
			Terminal.Start += (hook_Start)obj2;
			object obj3 = <>O.<2>__Terminal_TextPostProcess;
			if (obj3 == null)
			{
				hook_TextPostProcess val3 = Terminal_TextPostProcess;
				<>O.<2>__Terminal_TextPostProcess = val3;
				obj3 = (object)val3;
			}
			Terminal.TextPostProcess += (hook_TextPostProcess)obj3;
		}

		private static string Terminal_TextPostProcess(orig_TextPostProcess orig, Terminal self, string modifiedDisplayText, TerminalNode node)
		{
			if (modifiedDisplayText.Contains("[buyableItemsList]") && modifiedDisplayText.Contains("[unlockablesSelectionList]"))
			{
				int num = modifiedDisplayText.IndexOf(":");
				foreach (RegisteredUnlockable registeredUnlockable in registeredUnlockables)
				{
					if (registeredUnlockable.StoreType == StoreType.ShipUpgrade && !registeredUnlockable.disabled)
					{
						string unlockableName = registeredUnlockable.unlockable.unlockableName;
						int price = registeredUnlockable.price;
						string value = $"\n* {unlockableName}    //    Price: ${price}";
						modifiedDisplayText = modifiedDisplayText.Insert(num + 1, value);
					}
				}
			}
			return orig.Invoke(self, modifiedDisplayText, node);
		}

		private static void Terminal_Start(orig_Start orig, Terminal self)
		{
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Expected O, but got Unknown
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Expected O, but got Unknown
			TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
			TerminalKeyword val2 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			List<RegisteredUnlockable> list = registeredUnlockables.FindAll((RegisteredUnlockable unlockable) => unlockable.price != -1).ToList();
			Plugin.logger.LogInfo((object)$"Adding {list.Count} items to terminal");
			foreach (RegisteredUnlockable item in list)
			{
				string unlockableName = item.unlockable.unlockableName;
				TerminalKeyword keyword3 = TerminalUtils.CreateTerminalKeyword(unlockableName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val);
				if (self.terminalNodes.allKeywords.Any((TerminalKeyword kw) => kw.word == keyword3.word))
				{
					Plugin.logger.LogInfo((object)("Keyword " + keyword3.word + " already registed, skipping."));
					continue;
				}
				int shipUnlockableID = StartOfRound.Instance.unlockablesList.unlockables.FindIndex((UnlockableItem unlockable) => unlockable.unlockableName == item.unlockable.unlockableName);
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					Debug.Log((object)"STARTOFROUND INSTANCE NOT FOUND");
				}
				if (item.price == -1 && (Object)(object)item.buyNode1 != (Object)null)
				{
					item.price = item.buyNode1.itemCost;
				}
				char c = unlockableName[unlockableName.Length - 1];
				string text = unlockableName;
				TerminalNode val3 = item.buyNode2;
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val3).name = unlockableName.Replace(" ", "-") + "BuyNode2";
					val3.displayText = "Ordered [variableAmount] " + text + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n";
					val3.clearPreviousText = true;
					val3.maxCharactersToType = 15;
				}
				val3.buyItemIndex = -1;
				val3.shipUnlockableID = shipUnlockableID;
				val3.buyUnlockable = true;
				val3.creatureName = unlockableName;
				val3.isConfirmationNode = false;
				val3.itemCost = item.price;
				val3.playSyncedClip = 0;
				TerminalNode val4 = item.buyNode1;
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val4).name = unlockableName.Replace(" ", "-") + "BuyNode1";
					val4.displayText = "You have requested to order " + text + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n";
					val4.clearPreviousText = true;
					val4.maxCharactersToType = 35;
				}
				val4.buyItemIndex = -1;
				val4.shipUnlockableID = shipUnlockableID;
				val4.creatureName = unlockableName;
				val4.isConfirmationNode = true;
				val4.overrideOptions = true;
				val4.itemCost = item.price;
				val4.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
				{
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "confirm"),
						result = val3
					},
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "deny"),
						result = result
					}
				};
				if (item.StoreType == StoreType.Decor)
				{
					item.unlockable.shopSelectionNode = val4;
				}
				else
				{
					item.unlockable.shopSelectionNode = null;
				}
				List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
				list2.Add(keyword3);
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
				list3.Add(new CompatibleNoun
				{
					noun = keyword3,
					result = val4
				});
				val.compatibleNouns = list3.ToArray();
				TerminalNode val5 = item.itemInfo;
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val5).name = unlockableName.Replace(" ", "-") + "InfoNode";
					val5.displayText = "[No information about this object was found.]\n\n";
					val5.clearPreviousText = true;
					val5.maxCharactersToType = 25;
				}
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list4 = val2.compatibleNouns.ToList();
				list4.Add(new CompatibleNoun
				{
					noun = keyword3,
					result = val5
				});
				val2.compatibleNouns = list4.ToArray();
				BuyableUnlockableAssetInfo buyableUnlockableAssetInfo = default(BuyableUnlockableAssetInfo);
				buyableUnlockableAssetInfo.itemAsset = item.unlockable;
				buyableUnlockableAssetInfo.keyword = keyword3;
				BuyableUnlockableAssetInfo item2 = buyableUnlockableAssetInfo;
				buyableUnlockableAssetInfos.Add(item2);
				Plugin.logger.LogInfo((object)(item.modName + " registered item: " + item.unlockable.unlockableName));
			}
			orig.Invoke(self);
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			orig.Invoke(self);
			Plugin.logger.LogInfo((object)$"Adding {registeredUnlockables.Count} unlockables to unlockables list");
			foreach (RegisteredUnlockable unlockable in registeredUnlockables)
			{
				unlockable.disabled = false;
				if (self.unlockablesList.unlockables.Any((UnlockableItem x) => x.unlockableName == unlockable.unlockable.unlockableName))
				{
					Plugin.logger.LogInfo((object)("Unlockable " + unlockable.unlockable.unlockableName + " already exists in unlockables list, skipping"));
					continue;
				}
				if ((Object)(object)unlockable.unlockable.prefabObject != (Object)null)
				{
					PlaceableShipObject componentInChildren = unlockable.unlockable.prefabObject.GetComponentInChildren<PlaceableShipObject>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.unlockableID = self.unlockablesList.unlockables.Count;
					}
				}
				self.unlockablesList.unlockables.Add(unlockable.unlockable);
			}
		}

		public static void RegisterUnlockable(UnlockableItemDef unlockable, int price = -1, StoreType storeType = StoreType.None)
		{
			RegisterUnlockable(unlockable.unlockable, storeType, null, null, null, price);
		}

		public static void RegisterUnlockable(UnlockableItem unlockable, int price = -1, StoreType storeType = StoreType.None)
		{
			RegisterUnlockable(unlockable, storeType, null, null, null, price);
		}

		public static void RegisterUnlockable(UnlockableItemDef unlockable, StoreType storeType = StoreType.None, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
		{
			RegisterUnlockable(unlockable.unlockable, storeType, buyNode1, buyNode2, itemInfo, price);
		}

		public static void RegisterUnlockable(UnlockableItem unlockable, StoreType storeType = StoreType.None, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
		{
			RegisteredUnlockable registeredUnlockable = new RegisteredUnlockable(unlockable, buyNode1, buyNode2, itemInfo, price);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			registeredUnlockable.modName = name;
			registeredUnlockable.StoreType = storeType;
			registeredUnlockables.Add(registeredUnlockable);
		}

		public static void DisableUnlockable(UnlockableItemDef unlockable)
		{
			DisableUnlockable(unlockable.unlockable);
		}

		public static void DisableUnlockable(UnlockableItem unlockable)
		{
			RegisteredUnlockable registeredUnlockable = registeredUnlockables.Find((RegisteredUnlockable unlock) => unlock.unlockable == unlockable);
			if (registeredUnlockable != null)
			{
				registeredUnlockable.disabled = true;
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					StartOfRound.Instance.unlockablesList.unlockables.Remove(registeredUnlockable.unlockable);
				}
			}
		}

		public static void UpdateUnlockablePrice(UnlockableItem shopItem, int price)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			TerminalKeyword val = Items.terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
			List<CompatibleNoun> source = val.compatibleNouns.ToList();
			RegisteredUnlockable registeredUnlockable = registeredUnlockables.Find((RegisteredUnlockable unlock) => unlock.unlockable == shopItem);
			if (registeredUnlockable != null && registeredUnlockable.price != -1)
			{
				registeredUnlockable.price = price;
			}
			if (!buyableUnlockableAssetInfos.Any((BuyableUnlockableAssetInfo x) => x.itemAsset == shopItem))
			{
				return;
			}
			BuyableUnlockableAssetInfo asset = buyableUnlockableAssetInfos.First((BuyableUnlockableAssetInfo x) => x.itemAsset == shopItem);
			if (!source.Any((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword))
			{
				return;
			}
			CompatibleNoun val2 = source.First((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
			TerminalNode result2 = val2.result;
			result2.itemCost = price;
			if (result2.terminalOptions.Length == 0)
			{
				return;
			}
			CompatibleNoun[] terminalOptions = result2.terminalOptions;
			foreach (CompatibleNoun val3 in terminalOptions)
			{
				if ((Object)(object)val3.result != (Object)null && val3.result.buyItemIndex != -1)
				{
					val3.result.itemCost = price;
				}
			}
		}
	}
	public class Utilities
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__StartOfRound_Start;

			public static hook_Start <1>__MenuManager_Start;
		}

		public static List<GameObject> prefabsToFix = new List<GameObject>();

		public static List<GameObject> fixedPrefabs = new List<GameObject>();

		public static void Init()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			Plugin.logger.LogInfo((object)"Utilities.Init()");
			object obj = <>O.<0>__StartOfRound_Start;
			if (obj == null)
			{
				hook_Start val = StartOfRound_Start;
				<>O.<0>__StartOfRound_Start = val;
				obj = (object)val;
			}
			StartOfRound.Start += (hook_Start)obj;
			object obj2 = <>O.<1>__MenuManager_Start;
			if (obj2 == null)
			{
				hook_Start val2 = MenuManager_Start;
				<>O.<1>__MenuManager_Start = val2;
				obj2 = (object)val2;
			}
			MenuManager.Start += (hook_Start)obj2;
		}

		private static void StartOfRound_Start(orig_Start orig, StartOfRound self)
		{
			AudioMixer diageticMixer = SoundManager.Instance.diageticMixer;
			Plugin.logger.LogInfo((object)("Diagetic mixer is " + ((Object)diageticMixer).name));
			Plugin.logger.LogInfo((object)$"Found {prefabsToFix.Count} prefabs to fix");
			List<GameObject> list = new List<GameObject>();
			for (int num = prefabsToFix.Count - 1; num >= 0; num--)
			{
				GameObject val = prefabsToFix[num];
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val2 in array)
				{
					if (!((Object)(object)val2.outputAudioMixerGroup == (Object)null) && ((Object)val2.outputAudioMixerGroup.audioMixer).name == "Diagetic")
					{
						AudioMixerGroup val3 = diageticMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0];
						if ((Object)(object)val3 != (Object)null)
						{
							val2.outputAudioMixerGroup = val3;
							Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to Diagetic:" + ((Object)val3).name));
							list.Add(val);
						}
					}
				}
			}
			foreach (GameObject item in list)
			{
				prefabsToFix.Remove(item);
			}
			orig.Invoke(self);
		}

		private static void MenuManager_Start(orig_Start orig, MenuManager self)
		{
			orig.Invoke(self);
			if ((Object)(object)((Component)self).GetComponent<AudioSource>() == (Object)null)
			{
				return;
			}
			AudioMixer audioMixer = ((Component)self).GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer;
			List<GameObject> list = new List<GameObject>();
			for (int num = prefabsToFix.Count - 1; num >= 0; num--)
			{
				GameObject val = prefabsToFix[num];
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val2 in array)
				{
					if (!((Object)(object)val2.outputAudioMixerGroup == (Object)null) && ((Object)val2.outputAudioMixerGroup.audioMixer).name == "NonDiagetic")
					{
						AudioMixerGroup val3 = audioMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0];
						if ((Object)(object)val3 != (Object)null)
						{
							val2.outputAudioMixerGroup = val3;
							Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to NonDiagetic:" + ((Object)val3).name));
							list.Add(val);
						}
					}
				}
			}
			foreach (GameObject item in list)
			{
				prefabsToFix.Remove(item);
			}
		}

		public static void FixMixerGroups(GameObject prefab)
		{
			if (!fixedPrefabs.Contains(prefab))
			{
				fixedPrefabs.Add(prefab);
				prefabsToFix.Add(prefab);
			}
		}
	}
	public class Weathers
	{
		public class CustomWeather
		{
			public string name;

			public int weatherVariable1;

			public int weatherVariable2;

			public WeatherEffect weatherEffect;

			public Levels.LevelTypes levels;

			public string[] spawnLevelOverrides;

			public CustomWeather(string name, WeatherEffect weatherEffect, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null, int weatherVariable1 = 0, int weatherVariable2 = 0)
			{
				this.name = name;
				this.weatherVariable1 = weatherVariable1;
				this.weatherVariable2 = weatherVariable2;
				this.weatherEffect = weatherEffect;
				this.levels = levels;
				this.spawnLevelOverrides = spawnLevelOverrides;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__TimeOfDay_Awake;

			public static hook_Awake <1>__StartOfRound_Awake;
		}

		public static Dictionary<int, CustomWeather> customWeathers = new Dictionary<int, CustomWeather>();

		public static int numCustomWeathers = 0;

		public static void Init()
		{
			//IL_002f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			new Hook((MethodBase)typeof(Enum).GetMethod("ToString", new Type[0]), typeof(Weathers).GetMethod("ToStringHook"));
			object obj = <>O.<0>__TimeOfDay_Awake;
			if (obj == null)
			{
				hook_Awake val = TimeOfDay_Awake;
				<>O.<0>__TimeOfDay_Awake = val;
				obj = (object)val;
			}
			TimeOfDay.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__StartOfRound_Awake;
			if (obj2 == null)
			{
				hook_Awake val2 = StartOfRound_Awake;
				<>O.<1>__StartOfRound_Awake = val2;
				obj2 = (object)val2;
			}
			StartOfRound.Awake += (hook_Awake)obj2;
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			//IL_0119: 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_0126: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			foreach (KeyValuePair<int, CustomWeather> customWeather in customWeathers)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = customWeather.Value.levels.HasFlag(Levels.LevelTypes.All) || (customWeather.Value.spawnLevelOverrides != null && customWeather.Value.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag)
					{
						Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
						List<RandomWeatherWithVariables> list = val.randomWeathers.ToList();
						if (flag || customWeather.Value.levels.HasFlag(levelTypes))
						{
							list.Add(new RandomWeatherWithVariables
							{
								weatherType = (LevelWeatherType)customWeather.Key,
								weatherVariable = customWeather.Value.weatherVariable1,
								weatherVariable2 = customWeather.Value.weatherVariable2
							});
							Plugin.logger.LogInfo((object)$"Added weather {customWeather.Value.name} to level {((Object)val).name} at weather index: {customWeather.Key}");
						}
						val.randomWeathers = list.ToArray();
					}
				}
			}
			orig.Invoke(self);
		}

		private static void TimeOfDay_Awake(orig_Awake orig, TimeOfDay self)
		{
			List<WeatherEffect> list = self.effects.ToList();
			int num = 0;
			foreach (KeyValuePair<int, CustomWeather> customWeather in customWeathers)
			{
				if (customWeather.Key > num)
				{
					num = customWeather.Key;
				}
			}
			while (list.Count <= num)
			{
				list.Add(null);
			}
			foreach (KeyValuePair<int, CustomWeather> customWeather2 in customWeathers)
			{
				list[customWeather2.Key] = customWeather2.Value.weatherEffect;
			}
			self.effects = list.ToArray();
			orig.Invoke(self);
		}

		public static string ToStringHook(Func<Enum, string> orig, Enum self)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			if (self.GetType() == typeof(LevelWeatherType) && customWeathers.ContainsKey((int)(LevelWeatherType)(object)self))
			{
				return customWeathers[(int)(LevelWeatherType)(object)self].name;
			}
			return orig(self);
		}

		public static void RegisterWeather(WeatherDef weather)
		{
			RegisterWeather(weather.weatherName, weather.weatherEffect, weather.levels, weather.levelOverrides, weather.weatherVariable1, weather.weatherVariable2);
		}

		public static void RegisterWeather(string name, WeatherEffect weatherEffect, Levels.LevelTypes levels = Levels.LevelTypes.None, int weatherVariable1 = 0, int weatherVariable2 = 0)
		{
			Array values = Enum.GetValues(typeof(LevelWeatherType));
			int num = values.Length - 1;
			num += numCustomWeathers;
			numCustomWeathers++;
			Plugin.logger.LogInfo((object)$"Registering weather {name} at index {num - 1}");
			customWeathers.Add(num, new CustomWeather(name, weatherEffect, levels, null, weatherVariable1, weatherVariable2));
		}

		public static void RegisterWeather(string name, WeatherEffect weatherEffect, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null, int weatherVariable1 = 0, int weatherVariable2 = 0)
		{
			Array values = Enum.GetValues(typeof(LevelWeatherType));
			int num = values.Length - 1;
			num += numCustomWeathers;
			numCustomWeathers++;
			Plugin.logger.LogInfo((object)$"Registering weather {name} at index {num - 1}");
			customWeathers.Add(num, new CustomWeather(name, weatherEffect, levels, spawnLevelOverrides, weatherVariable1, weatherVariable2));
		}

		public static void RemoveWeather(string levelName, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			foreach (KeyValuePair<int, CustomWeather> entry in customWeathers)
			{
				if (!(entry.Value.name == levelName) || !((Object)(object)StartOfRound.Instance != (Object)null))
				{
					continue;
				}
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
					if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
					{
						continue;
					}
					Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
					if (flag || levelFlags.HasFlag(levelTypes))
					{
						List<RandomWeatherWithVariables> list = val.randomWeathers.ToList();
						list.RemoveAll((RandomWeatherWithVariables item) => (int)item.weatherType == entry.Key);
						val.randomWeathers = list.ToArray();
					}
				}
			}
		}
	}
}
namespace LethalLib.Extras
{
	[CreateAssetMenu(menuName = "ScriptableObjects/DungeonDef")]
	public class DungeonDef : ScriptableObject
	{
		public DungeonFlow dungeonFlow;

		[Range(0f, 300f)]
		public int rarity;

		public AudioClip firstTimeDungeonAudio;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/DungeonGraphLine")]
	public class DungeonGraphLineDef : ScriptableObject
	{
		public GraphLine graphLine;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/GameObjectChance")]
	public class GameObjectChanceDef : ScriptableObject
	{
		public GameObjectChance gameObjectChance;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/SpawnableMapObject")]
	public class SpawnableMapObjectDef : ScriptableObject
	{
		public SpawnableMapObject spawnableMapObject;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/SpawnableOutsideObject")]
	public class SpawnableOutsideObjectDef : ScriptableObject
	{
		public SpawnableOutsideObjectWithRarity spawnableMapObject;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/UnlockableItem")]
	public class UnlockableItemDef : ScriptableObject
	{
		public StoreType storeType = StoreType.None;

		public UnlockableItem unlockable;
	}
	[CreateAssetMenu(menuName = "ScriptableObjects/WeatherDef")]
	public class WeatherDef : ScriptableObject
	{
		public string weatherName;

		public Levels.LevelTypes levels = Levels.LevelTypes.None;

		public string[] levelOverrides;

		public int weatherVariable1;

		public int weatherVariable2;

		public WeatherEffect weatherEffect;
	}
}

BepInEx/plugins/Cheaper_Fuel_Company.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Cheaper_Fuel_Company")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Cheaper_Fuel_Company")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fb631837-abf8-432d-9854-a054c752c77f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Cheaper_Fuel_CompanyBase;

[BepInPlugin("LCMOD.Cheaper_Fuel_Company", "Cheaper_Fuel_Company", "1.0.0")]
public class Cheaper_Fuel_CompanyBase : BaseUnityPlugin
{
	public const string MODGUID = "LCMOD.Cheaper_Fuel_Company";

	public const string MODNAME = "Cheaper_Fuel_Company";

	public const string MODVERSION = "1.0.0";

	private readonly Harmony harmony = new Harmony("LCMOD.Cheaper_Fuel_Company");

	public static Cheaper_Fuel_CompanyBase Instance;

	public static ManualLogSource logger;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		logger = ((BaseUnityPlugin)this).Logger;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod LCMOD.Cheaper_Fuel_Company is loaded!");
		harmony.PatchAll(Assembly.GetExecutingAssembly());
	}
}
[HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")]
internal class LoadNewNodeIfAffordablePatch
{
	public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> codes)
	{
		List<CodeInstruction> list = codes.ToList();
		for (int i = 0; i < list.Count - 7; i++)
		{
			if (list[i].opcode == OpCodes.Ldarg_1 && list[i + 1].opcode == OpCodes.Ldfld && list[i + 1].operand.ToString().Contains("buyRerouteToMoon") && list[i + 2].opcode == OpCodes.Ldc_I4_M1 && list[i + 4].opcode == OpCodes.Ldarg_0 && list[i + 5].opcode == OpCodes.Ldarg_1 && list[i + 6].opcode == OpCodes.Ldfld && list[i + 6].operand.ToString().Contains("itemCost") && list[i + 7].opcode == OpCodes.Stfld && list[i + 7].operand.ToString().Contains("totalCostOfItems"))
			{
				list[i + 5].opcode = OpCodes.Nop;
				list[i + 6].opcode = OpCodes.Ldc_I4_0;
				list[i + 6].operand = null;
			}
		}
		Cheaper_Fuel_CompanyBase.logger.LogWarning((object)"Terminal::LoadNewNodeIfAffordable: Changing totalCostOfItems to 0 for moons!");
		return list.AsEnumerable();
	}
}

BepInEx/plugins/CustomSounds.dll

Decompiled 8 months 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.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomSounds.Networking;
using CustomSounds.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using LCSoundTool;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CustomSounds")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomSounds")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9e086160-a7fd-4721-ba09-3e8534cb7011")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace CustomSounds
{
	[BepInPlugin("CustomSounds", "Custom Sounds", "2.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string PLUGIN_GUID = "CustomSounds";

		private const string PLUGIN_NAME = "Custom Sounds";

		private const string PLUGIN_VERSION = "2.2.0";

		public static Plugin Instance;

		internal ManualLogSource logger;

		private Harmony harmony;

		public HashSet<string> currentSounds = new HashSet<string>();

		public HashSet<string> oldSounds = new HashSet<string>();

		public HashSet<string> modifiedSounds = new HashSet<string>();

		public Dictionary<string, string> soundHashes = new Dictionary<string, string>();

		public Dictionary<string, string> soundPacks = new Dictionary<string, string>();

		public static ConfigEntry<KeyboardShortcut> AcceptSyncKey;

		public ConfigEntry<bool> configUseNetworking;

		private Dictionary<string, string> customSoundNames = new Dictionary<string, string>();

		public static bool Initialized { get; private set; }

		private void Awake()
		{
			//IL_0065: 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_0089: Expected O, but got Unknown
			if (!((Object)(object)Instance == (Object)null))
			{
				return;
			}
			Instance = this;
			logger = Logger.CreateLogSource("CustomSounds");
			configUseNetworking = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "EnableNetworking", true, "Whether or not to use the networking built into this plugin. If set to true everyone in the lobby needs CustomSounds to join and also \"EnableNetworking\" set to true.");
			AcceptSyncKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Experimental", "AcceptSyncKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Key to accept audio sync.");
			harmony = new Harmony("CustomSounds");
			harmony.PatchAll(typeof(TerminalParsePlayerSentencePatch));
			harmony.PatchAll(typeof(RemapKeyPatch));
			if (configUseNetworking.Value)
			{
				harmony.PatchAll(typeof(NetworkObjectManager));
			}
			modifiedSounds = new HashSet<string>();
			string customSoundsFolderPath = GetCustomSoundsFolderPath();
			if (!Directory.Exists(customSoundsFolderPath))
			{
				logger.LogInfo((object)"\"CustomSounds\" folder not found. Creating it now.");
				Directory.CreateDirectory(customSoundsFolderPath);
			}
			string path = Path.Combine(Paths.BepInExConfigPath);
			try
			{
				List<string> list = File.ReadAllLines(path).ToList();
				int num = list.FindIndex((string line) => line.StartsWith("HideManagerGameObject"));
				if (num != -1)
				{
					logger.LogInfo((object)"\"hideManagerGameObject\" value not correctly set. Fixing it now.");
					list[num] = "HideManagerGameObject = true";
				}
				File.WriteAllLines(path, list);
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Error modifying config file: " + ex.Message));
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			logger.LogInfo((object)"Plugin CustomSounds is loaded!");
		}

		internal void Start()
		{
			Initialize();
		}

		internal void OnDestroy()
		{
			Initialize();
		}

		internal void Initialize()
		{
			if (!Initialized)
			{
				Initialized = true;
				DeleteTempFolder();
				ReloadSounds(serverSync: false, isTemporarySync: false);
			}
		}

		private void OnApplicationQuit()
		{
			DeleteTempFolder();
		}

		public GameObject LoadNetworkPrefabFromEmbeddedResource()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = "CustomSounds.Bundle.audionetworkhandler";
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			if (stream == null)
			{
				Debug.LogError((object)"Asset bundle not found in embedded resources.");
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			AssetBundle val = AssetBundle.LoadFromMemory(array);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Failed to load AssetBundle from memory.");
				return null;
			}
			return val.LoadAsset<GameObject>("audionetworkhandler");
		}

		public void DeleteTempFolder()
		{
			string customSoundsTempFolderPath = GetCustomSoundsTempFolderPath();
			if (Directory.Exists(customSoundsTempFolderPath))
			{
				try
				{
					Directory.Delete(customSoundsTempFolderPath, recursive: true);
					logger.LogInfo((object)"Temporary-Sync folder deleted successfully.");
				}
				catch (Exception ex)
				{
					logger.LogError((object)("Error deleting Temporary-Sync folder: " + ex.Message));
				}
			}
		}

		public string GetCustomSoundsFolderPath()
		{
			return Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "CustomSounds");
		}

		public string GetCustomSoundsTempFolderPath()
		{
			return Path.Combine(GetCustomSoundsFolderPath(), "Temporary-Sync");
		}

		public static byte[] SerializeWavToBytes(string filePath)
		{
			try
			{
				return File.ReadAllBytes(filePath);
			}
			catch (Exception ex)
			{
				Console.WriteLine("An error occurred: " + ex.Message);
				return null;
			}
		}

		public static string SerializeWavToBase64(string filePath)
		{
			try
			{
				byte[] inArray = File.ReadAllBytes(filePath);
				return Convert.ToBase64String(inArray);
			}
			catch (Exception ex)
			{
				Console.WriteLine("An error occurred: " + ex.Message);
				return null;
			}
		}

		public static void DeserializeBytesToWav(byte[] byteArray, string audioFileName)
		{
			try
			{
				string customSoundsTempFolderPath = Instance.GetCustomSoundsTempFolderPath();
				if (!Directory.Exists(customSoundsTempFolderPath))
				{
					Instance.logger.LogInfo((object)"\"Temporary-Sync\" folder not found. Creating it now.");
					Directory.CreateDirectory(customSoundsTempFolderPath);
				}
				File.WriteAllBytes(Path.Combine(customSoundsTempFolderPath, audioFileName), byteArray);
				Console.WriteLine("WAV file \"" + audioFileName + "\" created!");
			}
			catch (Exception ex)
			{
				Console.WriteLine("An error occurred: " + ex.Message);
			}
		}

		public static List<byte[]> SplitAudioData(byte[] audioData, int maxSegmentSize = 62000)
		{
			List<byte[]> list = new List<byte[]>();
			for (int i = 0; i < audioData.Length; i += maxSegmentSize)
			{
				int num = Mathf.Min(maxSegmentSize, audioData.Length - i);
				byte[] array = new byte[num];
				Array.Copy(audioData, i, array, 0, num);
				list.Add(array);
			}
			return list;
		}

		public static byte[] CombineAudioSegments(List<byte[]> segments)
		{
			List<byte> list = new List<byte>();
			foreach (byte[] segment in segments)
			{
				list.AddRange(segment);
			}
			return list.ToArray();
		}

		public void ShowCustomTip(string header, string body, bool isWarning)
		{
			HUDManager.Instance.DisplayTip(header, body, isWarning, false, "LC_Tip1");
		}

		public void ForceUnsync()
		{
			DeleteTempFolder();
			ReloadSounds(serverSync: false, isTemporarySync: false);
		}

		public void RevertSounds()
		{
			HashSet<string> hashSet = new HashSet<string>();
			foreach (string currentSound in currentSounds)
			{
				string text = currentSound;
				if (currentSound.Contains("-"))
				{
					text = currentSound.Substring(0, currentSound.IndexOf("-"));
				}
				if (!hashSet.Contains(text))
				{
					logger.LogInfo((object)(text + " restored."));
					SoundTool.RestoreAudioClip(text);
					hashSet.Add(text);
				}
			}
			logger.LogInfo((object)"Original game sounds restored.");
		}

		public static string CalculateMD5(string filename)
		{
			using MD5 mD = MD5.Create();
			using FileStream inputStream = File.OpenRead(filename);
			byte[] array = mD.ComputeHash(inputStream);
			return BitConverter.ToString(array).Replace("-", "").ToLowerInvariant();
		}

		public void ReloadSounds(bool serverSync, bool isTemporarySync)
		{
			oldSounds = new HashSet<string>(currentSounds);
			modifiedSounds.Clear();
			string directoryName = Path.GetDirectoryName(Paths.PluginPath);
			currentSounds.Clear();
			customSoundNames.Clear();
			string customSoundsTempFolderPath = GetCustomSoundsTempFolderPath();
			if (isTemporarySync)
			{
				logger.LogInfo((object)("Temporary folder: " + customSoundsTempFolderPath));
				if (Directory.Exists(customSoundsTempFolderPath))
				{
					ProcessDirectory(customSoundsTempFolderPath, serverSync, isTemporarySync: true);
				}
			}
			ProcessDirectory(directoryName, serverSync, isTemporarySync: false);
		}

		private void ProcessDirectory(string directoryPath, bool serverSync, bool isTemporarySync)
		{
			string[] directories = Directory.GetDirectories(directoryPath, "CustomSounds", SearchOption.AllDirectories);
			foreach (string text in directories)
			{
				string fileName = Path.GetFileName(Path.GetDirectoryName(text));
				ProcessSoundFiles(text, fileName, serverSync, isTemporarySync);
				string[] directories2 = Directory.GetDirectories(text);
				foreach (string text2 in directories2)
				{
					string fileName2 = Path.GetFileName(text2);
					ProcessSoundFiles(text2, fileName2, serverSync, isTemporarySync);
				}
			}
		}

		private (string soundName, int? percentage, string customName) ParseSoundFileName(string fullSoundName)
		{
			string[] array = fullSoundName.Split(new char[1] { '-' });
			string s = array[^1].Replace(".wav", "");
			if (int.TryParse(s, out var result))
			{
				string item = array[0];
				string item2 = string.Join(" ", array.Skip(1).Take(array.Length - 2));
				return (item, result, item2);
			}
			return (array[0], null, string.Join(" ", array.Skip(1)).Replace(".wav", ""));
		}

		private void ProcessSoundFiles(string directoryPath, string packName, bool serverSync, bool isTemporarySync)
		{
			string[] files = Directory.GetFiles(directoryPath, "*.wav");
			foreach (string text in files)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				(string soundName, int? percentage, string customName) tuple = ParseSoundFileName(fileNameWithoutExtension);
				string item = tuple.soundName;
				int? item2 = tuple.percentage;
				string item3 = tuple.customName;
				string text2 = (item2.HasValue ? $"{item}-{item3}-{item2.Value}" : (item + "-" + item3));
				string text3 = CalculateMD5(text);
				if (isTemporarySync || !currentSounds.Contains(text2))
				{
					if (soundHashes.TryGetValue(text2, out var value) && value != text3)
					{
						modifiedSounds.Add(text2);
					}
					AudioClip audioClip = SoundTool.GetAudioClip(directoryPath, "", text);
					SoundTool.ReplaceAudioClip(item, audioClip);
					soundHashes[text2] = text3;
					currentSounds.Add(text2);
					soundPacks[item] = packName;
					string text4 = "[" + packName + "] " + item + " sound replaced!";
					if (item2 > 0)
					{
						text4 += $" (Random chance: {item2}%)";
					}
					logger.LogInfo((object)text4);
					string key = item + (item2.HasValue ? $"-{item2.Value}-{item3}" : ("-" + item3));
					if (!string.IsNullOrEmpty(item3))
					{
						customSoundNames[key] = item3;
					}
					if (serverSync)
					{
						string text5 = Path.Combine(directoryPath, fileNameWithoutExtension + ".wav");
						logger.LogInfo((object)("[" + text5 + "] " + fileNameWithoutExtension + ".wav!"));
						AudioNetworkHandler.Instance.QueueAudioData(SerializeWavToBytes(text5), fileNameWithoutExtension + ".wav");
					}
				}
			}
		}

		public string ListAllSounds(bool isListing)
		{
			StringBuilder stringBuilder = new StringBuilder(isListing ? "Listing all currently loaded custom sounds:\n\n" : "Customsounds reloaded.\n\n");
			Dictionary<string, List<string>> soundsByPack = new Dictionary<string, List<string>>();
			Action<HashSet<string>, string> action = delegate(HashSet<string> soundsSet, string status)
			{
				foreach (string item5 in soundsSet)
				{
					(string soundName, int? percentage, string customName) tuple = ParseSoundFileName(item5);
					string item = tuple.soundName;
					int? item2 = tuple.percentage;
					string item3 = tuple.customName;
					string text = (item2.HasValue ? $" (Random: {item2.Value}%)" : "");
					string text2 = "";
					string key = item + (item2.HasValue ? $"-{item2.Value}-{item3}" : ("-" + item3));
					if (customSoundNames.TryGetValue(key, out var value))
					{
						text2 = " [" + value + "]";
					}
					string key2 = (soundPacks.ContainsKey(item) ? soundPacks[item] : "Unknown");
					if (!soundsByPack.ContainsKey(key2))
					{
						soundsByPack[key2] = new List<string>();
					}
					string item4 = (isListing ? (item + text + text2) : (item + " (" + status + ")" + text + text2));
					soundsByPack[key2].Add(item4);
				}
			};
			if (!isListing)
			{
				action(new HashSet<string>(currentSounds.Except(oldSounds)), "N¹");
				action(new HashSet<string>(oldSounds.Except(currentSounds)), "D²");
				action(new HashSet<string>(oldSounds.Intersect(currentSounds).Except(modifiedSounds)), "A.E³");
				action(new HashSet<string>(modifiedSounds), "M⁴");
			}
			else
			{
				action(new HashSet<string>(currentSounds), "N¹");
			}
			foreach (string key3 in soundsByPack.Keys)
			{
				stringBuilder.AppendLine(key3 + " :");
				foreach (string item6 in soundsByPack[key3])
				{
					stringBuilder.AppendLine("- " + item6);
				}
				stringBuilder.AppendLine();
			}
			if (!isListing)
			{
				stringBuilder.AppendLine("Footnotes:");
				stringBuilder.AppendLine("¹ N = New");
				stringBuilder.AppendLine("² D = Deleted");
				stringBuilder.AppendLine("³ A.E = Already Existed");
				stringBuilder.AppendLine("⁴ M = Modified");
				stringBuilder.AppendLine();
			}
			return stringBuilder.ToString();
		}
	}
}
namespace CustomSounds.Patches
{
	[HarmonyPatch]
	public class NetworkObjectManager
	{
		private static GameObject networkPrefab;

		private static GameObject networkHandlerHost;

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPrefix]
		public static void Init()
		{
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				networkPrefab = Plugin.Instance.LoadNetworkPrefabFromEmbeddedResource();
				networkPrefab.AddComponent<AudioNetworkHandler>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				Plugin.Instance.logger.LogInfo((object)"Created AudioNetworkHandler prefab");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//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)
			try
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					Plugin.Instance.logger.LogInfo((object)"Spawning network handler");
					networkHandlerHost = Object.Instantiate<GameObject>(networkPrefab, Vector3.zero, Quaternion.identity);
					if (networkHandlerHost.GetComponent<NetworkObject>().IsSpawned)
					{
						Debug.Log((object)"NetworkObject is spawned and active.");
					}
					else
					{
						Debug.Log((object)"Failed to spawn NetworkObject.");
					}
					networkHandlerHost.GetComponent<NetworkObject>().Spawn(true);
					if ((Object)(object)AudioNetworkHandler.Instance != (Object)null)
					{
						Debug.Log((object)"Successfully accessed AudioNetworkHandler instance.");
					}
					else
					{
						Debug.Log((object)"AudioNetworkHandler instance is null.");
					}
				}
			}
			catch
			{
				Plugin.Instance.logger.LogError((object)"Failed to spawned network handler");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		private static void DestroyNetworkHandler()
		{
			try
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					Plugin.Instance.logger.LogInfo((object)"Destroying network handler");
					Object.Destroy((Object)(object)networkHandlerHost);
					networkHandlerHost = null;
				}
			}
			catch
			{
				Plugin.Instance.logger.LogError((object)"Failed to destroy network handler");
			}
		}
	}
	[HarmonyPatch]
	public class RemapKeyPatch
	{
		public Harmony _harmony;

		public static InputActionAsset asset;

		private static string defaultKey;

		private static string path;

		public static string actionName;

		public static void UpdateInputActionAsset(string thing)
		{
			asset = InputActionAsset.FromJson("\r\n            {\r\n                \"maps\" : [\r\n                    {\r\n                        \"name\" : \"CustomSounds\",\r\n                        \"actions\": [\r\n                            {\"name\": \"" + actionName + "\", \"type\" : \"button\"}\r\n                        ],\r\n                        \"bindings\" : [\r\n                            {\"path\" : \"" + thing + "\", \"action\": \"" + actionName + "\"}\r\n                        ]\r\n                    }\r\n                ]\r\n            }");
		}

		[HarmonyPatch(typeof(KepRemapPanel), "LoadKeybindsUI")]
		[HarmonyPrefix]
		public static void AddRemappableKey(KepRemapPanel __instance)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			Debug.Log((object)("[CustomSounds] Default key for sync is " + defaultKey));
			for (int i = 0; i < __instance.remappableKeys.Count; i++)
			{
				if (__instance.remappableKeys[i].ControlName == "Accept Sync")
				{
					return;
				}
			}
			RemappableKey val = new RemappableKey();
			UpdateInputActionAsset(defaultKey);
			if ((Object)(object)asset == (Object)null)
			{
				Debug.LogError((object)"InputActionAsset is null.");
				return;
			}
			InputAction val2 = asset.FindAction("CustomSounds/" + actionName, false);
			if (val2 == null)
			{
				Debug.LogError((object)"Action 'CustomSounds/AcceptSyncAction' not found.");
				return;
			}
			InputActionReference currentInput = InputActionReference.Create(asset.FindAction("CustomSounds/" + actionName, false));
			val.ControlName = "Accept Sync";
			val.currentInput = currentInput;
			__instance.remappableKeys.Add(val);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		public static void ReadInput(PlayerControllerB __instance)
		{
			if (((((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject)) || __instance.isTestingPlayer) && Application.isFocused)
			{
				if (!Object.op_Implicit((Object)(object)asset) || !asset.enabled)
				{
					UpdateInputActionAsset(defaultKey);
					asset.Enable();
				}
				InputAction val = asset.FindAction("CustomSounds/" + actionName, false);
				if (val != null && val.WasPressedThisFrame() && AudioNetworkHandler.isRequestingSync)
				{
					Plugin.Instance.ShowCustomTip("CustomSounds Sync", "Sync request accepted successfully!", isWarning: false);
					AudioNetworkHandler.hasAcceptedSync = true;
					AudioNetworkHandler.isRequestingSync = false;
				}
			}
		}

		[HarmonyPatch(typeof(IngamePlayerSettings), "CompleteRebind")]
		[HarmonyPrefix]
		public static void SavingActionRebind(IngamePlayerSettings __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!(__instance.rebindingOperation.action.name != actionName))
			{
				string text = ((object)__instance.rebindingOperation.action).ToString();
				string text2 = text.Split('[', ']')[1];
				string value = text2.Replace("/Keyboard/", "");
				defaultKey = text2;
				try
				{
					KeyCode val = (KeyCode)Enum.Parse(typeof(KeyCode), value, ignoreCase: true);
					Plugin.AcceptSyncKey.Value = new KeyboardShortcut(val, Array.Empty<KeyCode>());
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("Erreur lors de la conversion de la chaîne en KeyCode: " + ex.Message));
				}
				UpdateInputActionAsset(defaultKey);
			}
		}

		[HarmonyPatch(typeof(KepRemapPanel), "ResetKeybindsUI")]
		[HarmonyPrefix]
		public static void ResetAcceptAction(KepRemapPanel __instance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Plugin.AcceptSyncKey.Value = new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>());
			defaultKey = "<Keyboard>/f8";
			UpdateInputActionAsset(defaultKey);
			bool flag = UpdateAcceptSyncKeybind(__instance, "<Keyboard>/f8");
		}

		private static bool UpdateAcceptSyncKeybind(KepRemapPanel panel, string defaultBinding)
		{
			foreach (RemappableKey remappableKey in panel.remappableKeys)
			{
				if (remappableKey.ControlName == "Accept Sync")
				{
					remappableKey.currentInput = InputActionReference.Create(asset.FindAction("CustomSounds/AcceptSyncAction", false));
					Debug.Log((object)"[CustomSounds] Found and updated 'Accept Sync' keybinding");
					return true;
				}
			}
			Debug.Log((object)"[CustomSounds] 'Accept Sync' keybinding not found");
			return false;
		}

		static RemapKeyPatch()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = Plugin.AcceptSyncKey.Value;
			defaultKey = "<Keyboard>/" + ((object)(KeyboardShortcut)(ref value)).ToString();
			path = Application.persistentDataPath + "/AcceptSyncButton.txt";
			actionName = "AcceptSyncAction";
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	public static class TerminalParsePlayerSentencePatch
	{
		public static bool Prefix(Terminal __instance, ref TerminalNode __result)
		{
			string[] array = __instance.screenText.text.Split(new char[1] { '\n' });
			if (array.Length == 0)
			{
				return true;
			}
			string[] array2 = array.Last().Trim().ToLower()
				.Split(new char[1] { ' ' });
			if (array2.Length == 0 || (array2[0] != "customsounds" && array2[0] != "cs"))
			{
				return true;
			}
			Plugin.Instance.logger.LogInfo((object)("Received terminal command: " + string.Join(" ", array2)));
			if (array2.Length > 1 && (array2[0] == "customsounds" || array2[0] == "cs"))
			{
				switch (array2[1])
				{
				case "reload":
				case "rl":
					Plugin.Instance.RevertSounds();
					Plugin.Instance.ReloadSounds(serverSync: false, isTemporarySync: false);
					__result = CreateTerminalNode(Plugin.Instance.ListAllSounds(isListing: false));
					return false;
				case "revert":
				case "rv":
					Plugin.Instance.RevertSounds();
					__result = CreateTerminalNode("Game sounds reverted to original.\n\n");
					return false;
				case "list":
				case "l":
					__result = CreateTerminalNode(Plugin.Instance.ListAllSounds(isListing: true));
					return false;
				case "help":
				case "h":
					if (NetworkManager.Singleton.IsHost)
					{
						__result = CreateTerminalNode("CustomSounds commands \n(Can also be used with 'CS' as an alias).\n\n>CUSTOMSOUNDS LIST/L\nTo display all currently loaded sounds\n\n>CUSTOMSOUNDS RELOAD/RL\nTo reload and apply sounds from the 'CustomSounds' folder and its subfolders.\n\n>CUSTOMSOUNDS REVERT/RV\nTo unload all custom sounds and restore original game sounds\n\n>CUSTOMSOUNDS SYNC/S\nTo start the sync of custom sounds with clients\n\n>CUSTOMSOUNDS FORCE-UNSYNC/FU\nTo force the unsync process for all clients\n\n");
					}
					else
					{
						__result = CreateTerminalNode("CustomSounds commands \n(Can also be used with 'CS' as an alias).\n\n>CUSTOMSOUNDS LIST/L\nTo display all currently loaded sounds\n\n>CUSTOMSOUNDS RELOAD/RL\nTo reload and apply sounds from the 'CustomSounds' folder and its subfolders.\n\n>CUSTOMSOUNDS REVERT/RV\nTo unload all custom sounds and restore original game sounds\n\n>CUSTOMSOUNDS UNSYNC/U\nUnsyncs sounds sent by the host.\n\n");
					}
					return false;
				case "sync":
				case "s":
					if (NetworkManager.Singleton.IsHost)
					{
						if (Plugin.Instance.configUseNetworking.Value)
						{
							__result = CreateTerminalNode("Custom sound sync initiated. \nSyncing sounds with clients...\n\n");
							Plugin.Instance.ReloadSounds(serverSync: true, isTemporarySync: false);
						}
						else
						{
							__result = CreateTerminalNode("Custom sound sync is currently disabled. \nPlease enable network support in the plugin config to use this feature.\n\n");
						}
					}
					else
					{
						__result = CreateTerminalNode("/!\\ ERROR /!\\ \nThis command can only be used by the host!\n\n");
					}
					return false;
				case "unsync":
				case "u":
					if (!NetworkManager.Singleton.IsHost)
					{
						__result = CreateTerminalNode("Unsyncing custom sounds. \nTemporary files deleted and original sounds reloaded.\n\n");
						Plugin.Instance.DeleteTempFolder();
						Plugin.Instance.ReloadSounds(serverSync: false, isTemporarySync: false);
					}
					else
					{
						__result = CreateTerminalNode("/!\\ ERROR /!\\ \nThis command cannot be used by the host!\n\n");
					}
					return false;
				case "fu":
				case "force-unsync":
					if (NetworkManager.Singleton.IsHost)
					{
						__result = CreateTerminalNode("Forcing unsync for all clients. \nAll client-side temporary synced files have been deleted, and original sounds reloaded.\n\n");
						AudioNetworkHandler.Instance.ForceUnsync();
					}
					else
					{
						__result = CreateTerminalNode("/!\\ ERROR /!\\ \nThis command can only be used by the host!\n\n");
					}
					return false;
				default:
					__result = CreateTerminalNode("Unknown customsounds command.\n\n");
					return false;
				}
			}
			return true;
		}

		private static TerminalNode CreateTerminalNode(string message)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.displayText = message;
			val.clearPreviousText = true;
			return val;
		}
	}
}
namespace CustomSounds.Networking
{
	public class AudioNetworkHandler : NetworkBehaviour
	{
		private struct AudioData
		{
			public List<byte[]> Segments;

			public string FileName;

			public AudioData(List<byte[]> segments, string fileName)
			{
				Segments = segments;
				FileName = fileName;
			}
		}

		private List<byte[]> receivedAudioSegments = new List<byte[]>();

		private string audioFileName;

		private int totalAudioFiles;

		private int processedAudioFiles;

		private int totalSegments;

		private int processedSegments;

		public static bool isRequestingSync;

		private float[] progressThresholds = new float[4] { 0.25f, 0.5f, 0.75f, 1f };

		private int lastThresholdIndex = -1;

		public static bool hasAcceptedSync;

		private Queue<AudioData> audioQueue = new Queue<AudioData>();

		private bool isSendingAudio = false;

		public static AudioNetworkHandler Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Debug.Log((object)"AudioNetworkHandler instance created.");
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				Debug.Log((object)"Extra AudioNetworkHandler instance destroyed.");
			}
		}

		public void QueueAudioData(byte[] audioData, string audioName)
		{
			List<byte[]> list = Plugin.SplitAudioData(audioData);
			totalSegments += list.Count;
			audioQueue.Enqueue(new AudioData(list, audioName));
			if (!isSendingAudio)
			{
				totalAudioFiles = audioQueue.Count;
				processedAudioFiles = 0;
				((MonoBehaviour)this).StartCoroutine(SendAudioDataQueue());
			}
		}

		private IEnumerator SendAudioDataQueue()
		{
			isSendingAudio = true;
			totalSegments = 0;
			processedSegments = 0;
			lastThresholdIndex = -1;
			RequestSyncWithClients();
			yield return (object)new WaitForSeconds(6f);
			isRequestingSync = false;
			DisplayStartingSyncMessageClientRpc();
			yield return (object)new WaitForSeconds(2f);
			while (audioQueue.Count > 0)
			{
				AudioData audioData = audioQueue.Dequeue();
				yield return ((MonoBehaviour)this).StartCoroutine(SendAudioDataCoroutine(audioData.Segments, audioData.FileName));
				processedAudioFiles++;
				UpdateProgress();
			}
			NotifyClientsQueueCompletedServerRpc();
			isSendingAudio = false;
		}

		private void RequestSyncWithClients()
		{
			foreach (NetworkClient connectedClients in NetworkManager.Singleton.ConnectedClientsList)
			{
				RequestSyncClientRpc(connectedClients.ClientId);
			}
		}

		[ClientRpc]
		private void RequestSyncClientRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3186703908u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, clientId);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3186703908u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((NetworkBehaviour)this).IsServer)
				{
					Plugin.Instance.ShowCustomTip("CustomSounds Sync", $"Press {Plugin.AcceptSyncKey.Value} to accept the audio sync request.", isWarning: false);
					isRequestingSync = true;
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void NotifyClientsQueueCompletedServerRpc(ServerRpcParams rpcParams = default(ServerRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(152710787u, rpcParams, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val, 152710787u, rpcParams, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ProcessLastAudioFileClientRpc();
				}
			}
		}

		public void ForceUnsync()
		{
			ForceUnsyncClientsClientRpc();
		}

		[ClientRpc]
		private void ForceUnsyncClientsClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3960362720u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3960362720u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).IsServer)
				{
					Debug.Log((object)"Forcing all clients to delete Temporary-Sync folder.");
					return;
				}
				Plugin.Instance.ShowCustomTip("CustomSounds Sync", "The CustomSounds sync has been reset by the host.\nTemporary files deleted and original sounds reloaded", isWarning: false);
				Plugin.Instance.DeleteTempFolder();
				Plugin.Instance.RevertSounds();
				Plugin.Instance.ReloadSounds(serverSync: false, isTemporarySync: false);
			}
		}

		[ClientRpc]
		private void ProcessLastAudioFileClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(234624598u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 234624598u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && hasAcceptedSync)
				{
					hasAcceptedSync = false;
					ProcessLastAudioFile();
					Debug.Log((object)"Reverting all sounds.");
					Plugin.Instance.RevertSounds();
					Debug.Log((object)"All sounds reverted!");
					Debug.Log((object)"Reloading all sounds.");
					Plugin.Instance.ReloadSounds(serverSync: false, isTemporarySync: true);
					Debug.Log((object)"All sounds reloaded!");
				}
			}
		}

		private void ProcessLastAudioFile()
		{
			if (receivedAudioSegments.Count > 0 && !string.IsNullOrEmpty(audioFileName))
			{
				byte[] byteArray = Plugin.CombineAudioSegments(receivedAudioSegments);
				Plugin.DeserializeBytesToWav(byteArray, audioFileName);
				receivedAudioSegments.Clear();
				audioFileName = null;
			}
		}

		public void SendAudioData(byte[] audioData, string audioName)
		{
			List<byte[]> list = Plugin.SplitAudioData(audioData);
			audioFileName = audioName;
			SendAudioMetaDataToClientsServerRpc(list.Count, audioName);
			((MonoBehaviour)this).StartCoroutine(SendAudioDataCoroutine(list, audioName));
		}

		[ServerRpc]
		public void SendAudioMetaDataToClientsServerRpc(int totalSegments, string fileName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3991320206u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, totalSegments);
				bool flag = fileName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(fileName, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3991320206u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				Debug.Log((object)$"Sending metadata to clients: {totalSegments} segments, file name: {fileName}");
				ReceiveAudioMetaDataClientRpc(totalSegments, fileName);
			}
		}

		private IEnumerator SendAudioDataCoroutine(List<byte[]> audioSegments, string audioName)
		{
			foreach (byte[] segment in audioSegments)
			{
				SendBytesToServerRpc(segment, audioName);
				processedSegments++;
				UpdateProgress();
				yield return (object)new WaitForSeconds(0.2f);
			}
		}

		[ServerRpc]
		public void SendBytesToServerRpc(byte[] audioSegment, string audioName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3131260794u, val, (RpcDelivery)0);
				bool flag = audioSegment != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(audioSegment, default(ForPrimitives));
				}
				bool flag2 = audioName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(audioName, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3131260794u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				Debug.Log((object)("Sending segment to server: " + audioName));
				ReceiveBytesClientRpc(audioSegment, audioName);
			}
		}

		[ClientRpc]
		public void ReceiveAudioMetaDataClientRpc(int totalSegments, string fileName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1027341762u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, totalSegments);
				bool flag = fileName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(fileName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1027341762u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				Debug.Log((object)$"Received metadata on client: {totalSegments} segments expected, file name: {fileName}");
				audioFileName = fileName;
				receivedAudioSegments.Clear();
			}
		}

		[ClientRpc]
		public void ReceiveBytesClientRpc(byte[] audioSegment, string audioName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2945580654u, val, (RpcDelivery)0);
				bool flag = audioSegment != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(audioSegment, default(ForPrimitives));
				}
				bool flag2 = audioName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(audioName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2945580654u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((NetworkBehaviour)this).IsServer && hasAcceptedSync)
			{
				if (!string.IsNullOrEmpty(audioName) && audioFileName != audioName)
				{
					ProcessLastAudioFile();
					audioFileName = audioName;
				}
				receivedAudioSegments.Add(audioSegment);
			}
		}

		[ClientRpc]
		private void DisplayStartingSyncMessageClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3964799390u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3964799390u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (hasAcceptedSync)
				{
					Plugin.Instance.ShowCustomTip("CustomSounds Sync", "Starting audio synchronization. Please wait...", isWarning: false);
					Plugin.Instance.DeleteTempFolder();
				}
				else if (((NetworkBehaviour)this).IsServer)
				{
					Plugin.Instance.ShowCustomTip("CustomSounds Sync", "Initiating audio synchronization. Sending files to clients...", isWarning: false);
				}
			}
		}

		private void UpdateProgress()
		{
			float progress = (float)processedSegments / (float)totalSegments;
			int currentThresholdIndex = GetCurrentThresholdIndex(progress);
			if (currentThresholdIndex > lastThresholdIndex)
			{
				lastThresholdIndex = currentThresholdIndex;
				UpdateProgressClientRpc(progress);
			}
		}

		private int GetCurrentThresholdIndex(float progress)
		{
			for (int num = progressThresholds.Length - 1; num >= 0; num--)
			{
				if (progress >= progressThresholds[num])
				{
					return num;
				}
			}
			return -1;
		}

		[ClientRpc]
		private void UpdateProgressClientRpc(float progress)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3902617409u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref progress, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3902617409u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || (!((NetworkBehaviour)this).IsServer && !hasAcceptedSync))
			{
				return;
			}
			string text = GenerateProgressBar(progress);
			if (progress < 1f)
			{
				if (!((NetworkBehaviour)this).IsServer)
				{
					Plugin.Instance.ShowCustomTip("CustomSounds Sync", "Sounds transfer progression:\n" + text, isWarning: false);
				}
			}
			else if (((NetworkBehaviour)this).IsServer)
			{
				Plugin.Instance.ShowCustomTip("CustomSounds Sync", "All sounds have been successfully sent!", isWarning: false);
			}
			else
			{
				Plugin.Instance.ShowCustomTip("CustomSounds Sync", "All sounds have been successfully received!", isWarning: false);
			}
		}

		private string GenerateProgressBar(float progress)
		{
			int num = 26;
			progress = Mathf.Clamp(progress, 0f, 1f);
			int num2 = (int)(progress * (float)num);
			return "[" + new string('#', num2) + new string('-', num - num2) + "] " + (int)(progress * 100f) + "%";
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_AudioNetworkHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3186703908u, new RpcReceiveHandler(__rpc_handler_3186703908));
			NetworkManager.__rpc_func_table.Add(152710787u, new RpcReceiveHandler(__rpc_handler_152710787));
			NetworkManager.__rpc_func_table.Add(3960362720u, new RpcReceiveHandler(__rpc_handler_3960362720));
			NetworkManager.__rpc_func_table.Add(234624598u, new RpcReceiveHandler(__rpc_handler_234624598));
			NetworkManager.__rpc_func_table.Add(3991320206u, new RpcReceiveHandler(__rpc_handler_3991320206));
			NetworkManager.__rpc_func_table.Add(3131260794u, new RpcReceiveHandler(__rpc_handler_3131260794));
			NetworkManager.__rpc_func_table.Add(1027341762u, new RpcReceiveHandler(__rpc_handler_1027341762));
			NetworkManager.__rpc_func_table.Add(2945580654u, new RpcReceiveHandler(__rpc_handler_2945580654));
			NetworkManager.__rpc_func_table.Add(3964799390u, new RpcReceiveHandler(__rpc_handler_3964799390));
			NetworkManager.__rpc_func_table.Add(3902617409u, new RpcReceiveHandler(__rpc_handler_3902617409));
		}

		private static void __rpc_handler_3186703908(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).RequestSyncClientRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_152710787(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ServerRpcParams server = rpcParams.Server;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((AudioNetworkHandler)(object)target).NotifyClientsQueueCompletedServerRpc(server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3960362720(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).ForceUnsyncClientsClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_234624598(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).ProcessLastAudioFileClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3991320206(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			int num = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref num);
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			string fileName = null;
			if (flag)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe(ref fileName, false);
			}
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((AudioNetworkHandler)(object)target).SendAudioMetaDataToClientsServerRpc(num, fileName);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_3131260794(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			byte[] audioSegment = null;
			if (flag)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref audioSegment, default(ForPrimitives));
			}
			bool flag2 = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
			string audioName = null;
			if (flag2)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe(ref audioName, false);
			}
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((AudioNetworkHandler)(object)target).SendBytesToServerRpc(audioSegment, audioName);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_1027341762(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int num = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref num);
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string fileName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref fileName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).ReceiveAudioMetaDataClientRpc(num, fileName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2945580654(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				byte[] audioSegment = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref audioSegment, default(ForPrimitives));
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				string audioName = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref audioName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).ReceiveBytesClientRpc(audioSegment, audioName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3964799390(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).DisplayStartingSyncMessageClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3902617409(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				float progress = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref progress, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AudioNetworkHandler)(object)target).UpdateProgressClientRpc(progress);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "AudioNetworkHandler";
		}
	}
}

BepInEx/plugins/GiftBoxRevert.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GiftBoxRevert.Patches;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("GiftBoxRevert")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Reverts the giftboxes content back to being double the intended amount")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GiftBoxRevert")]
[assembly: AssemblyTitle("GiftBoxRevert")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace GiftBoxRevert
{
	[BepInPlugin("GiftBoxRevert", "GiftBoxRevert", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private bool _patched;

		public static ManualLogSource Logger { get; set; }

		private void Awake()
		{
			if (_patched)
			{
				Logger.LogWarning((object)"Already loaded");
				return;
			}
			Logger = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(GiftBoxPatch), "GiftBoxRevert");
			Logger.LogInfo((object)"GiftBoxRevert is loaded!");
			_patched = true;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "GiftBoxRevert";

		public const string PLUGIN_NAME = "GiftBoxRevert";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace GiftBoxRevert.Patches
{
	internal class GiftBoxPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GiftBoxItem), "OpenGiftBoxServerRpc")]
		private static IEnumerable<CodeInstruction> TranspileOpenGiftBoxServerRpc(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(RoundManager), "scrapValueMultiplier"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_I4, (object)null, (string)null)
			}).Advance(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldc_R4, (object)2.5f),
				new CodeInstruction(OpCodes.Mul, (object)null)
			})
				.InstructionEnumeration();
		}
	}
}

BepInEx/plugins/LC_SoundTool.dll

Decompiled 8 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LCSoundTool.Networking;
using LCSoundTool.Patches;
using LCSoundTool.Resources;
using LCSoundTool.Utilities;
using LCSoundToolMod.Properties;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LC_SoundTool")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Various audio related functions. Mainly logs all sounds that are playing and what type of playback they're into the BepInEx console.")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("LC_SoundTool")]
[assembly: AssemblyTitle("LC_SoundTool")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/no00ob/LCSoundTool")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LCSoundToolMod
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LC_SoundTool";

		public const string PLUGIN_NAME = "LC_SoundTool";

		public const string PLUGIN_VERSION = "1.4.0";
	}
}
namespace LCSoundToolMod.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LCSoundToolMod.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] soundtool
		{
			get
			{
				object @object = ResourceManager.GetObject("soundtool", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace LCSoundTool
{
	public class AudioSourceExtension : MonoBehaviour
	{
		public AudioSource audioSource;

		public bool playOnAwake = false;

		public bool loop = false;

		private bool updateHasBeenLogged = false;

		private bool hasPlayed = false;

		private void OnEnable()
		{
			if (!((Object)(object)audioSource == (Object)null) && !audioSource.isPlaying)
			{
				if (playOnAwake)
				{
					audioSource.Play();
				}
				if (SoundTool.infoDebugging)
				{
					SoundTool.Instance.logger.LogDebug((object)$"(AudioSourceExtension) Started playback of {audioSource} with clip {audioSource.clip} in OnEnable function!");
				}
				updateHasBeenLogged = false;
				hasPlayed = false;
			}
		}

		private void OnDisable()
		{
			if (!((Object)(object)audioSource == (Object)null) && audioSource.isPlaying)
			{
				if (playOnAwake)
				{
					audioSource.Stop();
				}
				if (SoundTool.infoDebugging)
				{
					SoundTool.Instance.logger.LogDebug((object)$"(AudioSourceExtension) Stopped playback of {audioSource} with clip {audioSource.clip} in OnDisable function!");
				}
				updateHasBeenLogged = false;
				hasPlayed = false;
			}
		}

		private void Update()
		{
			if ((Object)(object)audioSource == (Object)null)
			{
				return;
			}
			if ((Object)(object)audioSource.clip == (Object)null)
			{
				hasPlayed = false;
			}
			if (audioSource.isPlaying)
			{
				updateHasBeenLogged = false;
			}
			else if (!((Behaviour)audioSource).isActiveAndEnabled)
			{
				hasPlayed = false;
			}
			else
			{
				if (!playOnAwake)
				{
					return;
				}
				if ((Object)(object)audioSource.clip != (Object)null && !hasPlayed)
				{
					audioSource.Play();
					if (SoundTool.infoDebugging)
					{
						SoundTool.Instance.logger.LogDebug((object)$"(AudioSourceExtension) Started playback of {audioSource} with clip {audioSource.clip} in Update function!");
					}
					updateHasBeenLogged = false;
					hasPlayed = true;
				}
				else if (!updateHasBeenLogged)
				{
					updateHasBeenLogged = true;
					if (SoundTool.infoDebugging)
					{
						SoundTool.Instance.logger.LogDebug((object)$"(AudioSourceExtension) Can not start playback of {audioSource} with missing clip in Update function!");
					}
				}
			}
		}
	}
	public class RandomAudioClip
	{
		public AudioClip clip;

		[Range(0f, 1f)]
		public float chance = 1f;

		public RandomAudioClip(AudioClip clip, float chance)
		{
			this.clip = clip;
			this.chance = chance;
		}
	}
	[BepInPlugin("LCSoundTool", "LC Sound Tool", "1.4.0")]
	public class SoundTool : BaseUnityPlugin
	{
		public enum AudioType
		{
			wav,
			ogg,
			mp3
		}

		private const string PLUGIN_GUID = "LCSoundTool";

		private const string PLUGIN_NAME = "LC Sound Tool";

		private ConfigEntry<bool> configUseNetworking;

		private ConfigEntry<bool> configSyncRandomSeed;

		private ConfigEntry<float> configPlayOnAwakePatchRepeatDelay;

		private readonly Harmony harmony = new Harmony("LCSoundTool");

		public static SoundTool Instance;

		internal ManualLogSource logger;

		public KeyboardShortcut toggleAudioSourceDebugLog;

		public KeyboardShortcut toggleIndepthDebugLog;

		public KeyboardShortcut toggleInformationalDebugLog;

		public bool wasKeyDown;

		public bool wasKeyDown2;

		public bool wasKeyDown3;

		public static bool debugAudioSources;

		public static bool indepthDebugging;

		public static bool infoDebugging;

		public static bool networkingInitialized { get; private set; }

		public static bool networkingAvailable { get; private set; }

		public static Dictionary<string, List<RandomAudioClip>> replacedClips { get; private set; }

		public static Dictionary<string, AudioClip> networkedClips => NetworkHandler.networkedAudioClips;

		public static Dictionary<string, AudioType> clipTypes { get; private set; }

		public static event Action ClientNetworkedAudioChanged
		{
			add
			{
				NetworkHandler.ClientNetworkedAudioChanged += value;
			}
			remove
			{
				NetworkHandler.ClientNetworkedAudioChanged -= value;
			}
		}

		public static event Action HostNetworkedAudioChanged
		{
			add
			{
				NetworkHandler.HostNetworkedAudioChanged += value;
			}
			remove
			{
				NetworkHandler.HostNetworkedAudioChanged -= value;
			}
		}

		public static bool IsDebuggingOn()
		{
			if (debugAudioSources || indepthDebugging || infoDebugging)
			{
				return true;
			}
			return false;
		}

		private void Awake()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			networkingAvailable = true;
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			configUseNetworking = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "EnableNetworking", false, "Whether or not to use the networking built into this plugin. If set to true everyone in the lobby needs LCSoundTool installed and networking enabled to join.");
			configSyncRandomSeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "SyncUnityRandomSeed", false, "Whether or not to sync the default Unity randomization seed with all clients. For this feature, networking has to be set to true. Will send the UnityEngine.Random.seed from the host to all clients automatically upon loading a networked scene.");
			configPlayOnAwakePatchRepeatDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Experimental", "NewPlayOnAwakePatchRepeatDelay", 90f, "How long to wait between checks for new playOnAwake AudioSources. Runs the same patching that is done when each scene is loaded with this delay between each run. DO NOT set too low or high. Anything below 10 or above 600 can cause issues. This time is in seconds. Set to 0 to disable rerunning the patch, but be warned that this might break runtime initialized playOnAwake AudioSources.");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			logger = Logger.CreateLogSource("LCSoundTool");
			logger.LogInfo((object)"Plugin LCSoundTool is loaded!");
			toggleAudioSourceDebugLog = new KeyboardShortcut((KeyCode)286, (KeyCode[])(object)new KeyCode[0]);
			toggleIndepthDebugLog = new KeyboardShortcut((KeyCode)286, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 });
			toggleInformationalDebugLog = new KeyboardShortcut((KeyCode)286, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 });
			debugAudioSources = false;
			indepthDebugging = false;
			infoDebugging = false;
			replacedClips = new Dictionary<string, List<RandomAudioClip>>();
			clipTypes = new Dictionary<string, AudioType>();
		}

		private void Start()
		{
			if (!configUseNetworking.Value)
			{
				networkingAvailable = false;
				Instance.logger.LogWarning((object)"Networking disabled. Mod in fully client side mode, but no networked actions can take place! You can safely ignore this if you want the mod to run fully client side.");
			}
			else
			{
				networkingAvailable = true;
			}
			if (configUseNetworking.Value)
			{
				logger.LogDebug((object)"Loading SoundTool AssetBundle...");
				Assets.bundle = AssetBundle.LoadFromMemory(LCSoundToolMod.Properties.Resources.soundtool);
				if ((Object)(object)Assets.bundle == (Object)null)
				{
					logger.LogError((object)"Failed to load SoundTool AssetBundle!");
				}
				else
				{
					logger.LogDebug((object)"Finished loading SoundTool AssetBundle!");
				}
			}
			harmony.PatchAll(typeof(AudioSourcePatch));
			if (configUseNetworking.Value)
			{
				harmony.PatchAll(typeof(GameNetworkManagerPatch));
				harmony.PatchAll(typeof(StartOfRoundPatch));
			}
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void Update()
		{
			if (configUseNetworking.Value)
			{
				if (!networkingInitialized)
				{
					if ((Object)(object)NetworkHandler.Instance != (Object)null)
					{
						networkingInitialized = true;
					}
				}
				else if ((Object)(object)NetworkHandler.Instance == (Object)null)
				{
					networkingInitialized = false;
				}
			}
			else
			{
				networkingInitialized = false;
			}
			if (((KeyboardShortcut)(ref toggleInformationalDebugLog)).IsDown() && !wasKeyDown3)
			{
				wasKeyDown3 = true;
				wasKeyDown2 = false;
				wasKeyDown = false;
			}
			if (((KeyboardShortcut)(ref toggleInformationalDebugLog)).IsUp() && wasKeyDown3)
			{
				wasKeyDown3 = false;
				wasKeyDown2 = false;
				wasKeyDown = false;
				infoDebugging = !infoDebugging;
				Instance.logger.LogDebug((object)$"Toggling informational debug logs {infoDebugging}!");
				return;
			}
			if (((KeyboardShortcut)(ref toggleIndepthDebugLog)).IsDown() && !wasKeyDown2)
			{
				wasKeyDown2 = true;
				wasKeyDown = false;
			}
			if (((KeyboardShortcut)(ref toggleIndepthDebugLog)).IsUp() && wasKeyDown2)
			{
				wasKeyDown2 = false;
				wasKeyDown = false;
				debugAudioSources = !debugAudioSources;
				indepthDebugging = debugAudioSources;
				infoDebugging = debugAudioSources;
				Instance.logger.LogDebug((object)$"Toggling in-depth AudioSource debug logs {debugAudioSources}!");
				return;
			}
			if (!wasKeyDown2 && !((KeyboardShortcut)(ref toggleIndepthDebugLog)).IsDown() && ((KeyboardShortcut)(ref toggleAudioSourceDebugLog)).IsDown() && !wasKeyDown)
			{
				wasKeyDown = true;
				wasKeyDown2 = false;
			}
			if (((KeyboardShortcut)(ref toggleAudioSourceDebugLog)).IsUp() && wasKeyDown)
			{
				wasKeyDown = false;
				wasKeyDown2 = false;
				debugAudioSources = !debugAudioSources;
				if (indepthDebugging && !debugAudioSources)
				{
					indepthDebugging = false;
				}
				Instance.logger.LogDebug((object)$"Toggling AudioSource debug logs {debugAudioSources}!");
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0013: 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)
			if (!((Object)(object)Instance == (Object)null))
			{
				PatchPlayOnAwakeAudio(scene);
				OnSceneLoadedNetworking();
				if (((Scene)(ref scene)).name.ToLower().Contains("level"))
				{
					((MonoBehaviour)this).StopAllCoroutines();
					((MonoBehaviour)this).StartCoroutine(PatchPlayOnAwakeDelayed(scene, 1f));
				}
			}
		}

		private IEnumerator PatchPlayOnAwakeDelayed(Scene scene, float wait)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (infoDebugging)
			{
				logger.LogDebug((object)$"Started playOnAwake patch coroutine with delay of {wait} seconds");
			}
			yield return (object)new WaitForSecondsRealtime(wait);
			if (infoDebugging)
			{
				logger.LogDebug((object)"Running playOnAwake patch coroutine!");
			}
			PatchPlayOnAwakeAudio(scene);
			float repeatWait = configPlayOnAwakePatchRepeatDelay.Value;
			if (repeatWait != 0f)
			{
				if (repeatWait < 10f)
				{
					repeatWait = 10f;
				}
				if (repeatWait > 600f)
				{
					repeatWait = 600f;
				}
				((MonoBehaviour)this).StartCoroutine(PatchPlayOnAwakeDelayed(scene, repeatWait));
			}
		}

		private void PatchPlayOnAwakeAudio(Scene scene)
		{
			if (infoDebugging)
			{
				Instance.logger.LogDebug((object)("Grabbing all playOnAwake AudioSources for loaded scene " + ((Scene)(ref scene)).name));
			}
			AudioSource[] allPlayOnAwakeAudioSources = GetAllPlayOnAwakeAudioSources();
			if (infoDebugging)
			{
				Instance.logger.LogDebug((object)$"Found a total of {allPlayOnAwakeAudioSources.Length} playOnAwake AudioSource(s)!");
				Instance.logger.LogDebug((object)$"Starting setup on {allPlayOnAwakeAudioSources.Length} playOnAwake AudioSource(s)...");
			}
			AudioSource[] array = allPlayOnAwakeAudioSources;
			AudioSourceExtension audioSourceExtension = default(AudioSourceExtension);
			foreach (AudioSource val in array)
			{
				val.Stop();
				if (((Component)((Component)val).transform).TryGetComponent<AudioSourceExtension>(ref audioSourceExtension))
				{
					audioSourceExtension.audioSource = val;
					audioSourceExtension.playOnAwake = true;
					audioSourceExtension.loop = val.loop;
					val.playOnAwake = false;
					if (infoDebugging)
					{
						Instance.logger.LogDebug((object)$"-Set- {Array.IndexOf(allPlayOnAwakeAudioSources, val) + 1} {val} done!");
					}
					continue;
				}
				AudioSourceExtension audioSourceExtension2 = ((Component)val).gameObject.AddComponent<AudioSourceExtension>();
				audioSourceExtension2.audioSource = val;
				audioSourceExtension2.playOnAwake = true;
				audioSourceExtension2.loop = val.loop;
				val.playOnAwake = false;
				if (infoDebugging)
				{
					Instance.logger.LogDebug((object)$"-Add- {Array.IndexOf(allPlayOnAwakeAudioSources, val) + 1} {val} done!");
				}
			}
			if (infoDebugging)
			{
				Instance.logger.LogDebug((object)$"Done setting up {allPlayOnAwakeAudioSources.Length} playOnAwake AudioSources!");
			}
		}

		private void OnSceneLoadedNetworking()
		{
			if (networkingAvailable && networkingInitialized && configSyncRandomSeed.Value)
			{
				int num = (int)DateTime.Now.Ticks;
				Random.InitState(num);
				SendUnityRandomSeed(num);
			}
		}

		public AudioSource[] GetAllPlayOnAwakeAudioSources()
		{
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
			List<AudioSource> list = new List<AudioSource>();
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].playOnAwake)
				{
					list.Add(array[i]);
				}
			}
			return list.ToArray();
		}

		public static void ReplaceAudioClip(string originalName, AudioClip newClip)
		{
			if (string.IsNullOrEmpty(originalName))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without original clip specified! This is not allowed.");
				return;
			}
			if ((Object)(object)newClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without new clip specified! This is not allowed.");
				return;
			}
			string name = newClip.GetName();
			float num = 100f;
			if (name.Contains("-"))
			{
				string[] array = name.Split('-');
				if (array.Length > 1)
				{
					string s = array[^1];
					if (int.TryParse(s, out var result))
					{
						num = (float)result * 0.01f;
						name = string.Join("-", array, 0, array.Length - 1);
					}
				}
			}
			if (replacedClips.ContainsKey(originalName) && num >= 100f)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip that already has been replaced with 100% chance of playback! This is not allowed.");
				return;
			}
			num = Mathf.Clamp01(num);
			if (replacedClips.ContainsKey(originalName))
			{
				replacedClips[originalName].Add(new RandomAudioClip(newClip, num));
			}
			else
			{
				replacedClips[originalName] = new List<RandomAudioClip>
				{
					new RandomAudioClip(newClip, num)
				};
			}
			float num2 = 0f;
			for (int i = 0; i < replacedClips[originalName].Count(); i++)
			{
				num2 += replacedClips[originalName][i].chance;
			}
			if ((num2 < 1f || num2 > 1f) && replacedClips[originalName].Count() > 1)
			{
				Instance.logger.LogDebug((object)$"The current total combined chance for replaced {replacedClips[originalName].Count()} random audio clips for audio clip {originalName} does not equal 100% (at least yet?)");
			}
			else if (num2 == 1f && replacedClips[originalName].Count() > 1)
			{
				Instance.logger.LogDebug((object)$"The current total combined chance for replaced {replacedClips[originalName].Count()} random audio clips for audio clip {originalName} is equal to 100%");
			}
		}

		public static void ReplaceAudioClip(AudioClip originalClip, AudioClip newClip)
		{
			if ((Object)(object)originalClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without original clip specified! This is not allowed.");
			}
			else if ((Object)(object)newClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without new clip specified! This is not allowed.");
			}
			else
			{
				ReplaceAudioClip(originalClip.GetName(), newClip);
			}
		}

		public static void ReplaceAudioClip(string originalName, AudioClip newClip, float chance)
		{
			if (string.IsNullOrEmpty(originalName))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without original clip specified! This is not allowed.");
				return;
			}
			if ((Object)(object)newClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without new clip specified! This is not allowed.");
				return;
			}
			string name = newClip.GetName();
			if (replacedClips.ContainsKey(originalName) && chance >= 100f)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip that already has been replaced with 100% chance of playback! This is not allowed.");
				return;
			}
			chance = Mathf.Clamp01(chance);
			if (replacedClips.ContainsKey(originalName))
			{
				replacedClips[originalName].Add(new RandomAudioClip(newClip, chance));
			}
			else
			{
				replacedClips[originalName] = new List<RandomAudioClip>
				{
					new RandomAudioClip(newClip, chance)
				};
			}
			float num = 0f;
			for (int i = 0; i < replacedClips[originalName].Count(); i++)
			{
				num += replacedClips[originalName][i].chance;
			}
			if ((num < 1f || num > 1f) && replacedClips[originalName].Count() > 1)
			{
				Instance.logger.LogDebug((object)$"The current total combined chance for replaced {replacedClips[originalName].Count()} random audio clips for audio clip {originalName} does not equal 100% (at least yet?)");
			}
			else if (num == 1f && replacedClips[originalName].Count() > 1)
			{
				Instance.logger.LogDebug((object)$"The current total combined chance for replaced {replacedClips[originalName].Count()} random audio clips for audio clip {originalName} is equal to 100%");
			}
		}

		public static void ReplaceAudioClip(AudioClip originalClip, AudioClip newClip, float chance)
		{
			if ((Object)(object)originalClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without original clip specified! This is not allowed.");
			}
			else if ((Object)(object)newClip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to replace an audio clip without new clip specified! This is not allowed.");
			}
			else
			{
				ReplaceAudioClip(originalClip.GetName(), newClip, chance);
			}
		}

		public static void RemoveRandomAudioClip(string name, float chance)
		{
			if (string.IsNullOrEmpty(name))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to restore an audio clip without original clip specified! This is not allowed.");
			}
			else if (!replacedClips.ContainsKey(name))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to restore an audio clip that does not exist! This is not allowed.");
			}
			else
			{
				if (!(chance > 0f))
				{
					return;
				}
				for (int i = 0; i < replacedClips[name].Count(); i++)
				{
					if (replacedClips[name][i].chance == chance)
					{
						replacedClips[name].RemoveAt(i);
						break;
					}
				}
			}
		}

		public static void RestoreAudioClip(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to restore an audio clip without original clip specified! This is not allowed.");
			}
			else if (!replacedClips.ContainsKey(name))
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to restore an audio clip that does not exist! This is not allowed.");
			}
			else
			{
				replacedClips.Remove(name);
			}
		}

		public static void RestoreAudioClip(AudioClip clip)
		{
			if ((Object)(object)clip == (Object)null)
			{
				Instance.logger.LogWarning((object)"Plugin LCSoundTool is trying to restore an audio clip without original clip specified! This is not allowed.");
			}
			else
			{
				RestoreAudioClip(clip.GetName());
			}
		}

		public static AudioClip GetAudioClip(string modFolder, string soundName)
		{
			return GetAudioClip(modFolder, string.Empty, soundName);
		}

		public static AudioClip GetAudioClip(string modFolder, string subFolder, string soundName)
		{
			AudioType audioType = AudioType.wav;
			bool flag = true;
			string text = " ";
			string text2 = Path.Combine(Paths.PluginPath, modFolder, subFolder, soundName);
			string text3 = Path.Combine(Paths.PluginPath, modFolder, soundName);
			string path = Path.Combine(Paths.PluginPath, modFolder, subFolder);
			string text4 = Path.Combine(Paths.PluginPath, subFolder, soundName);
			string path2 = Path.Combine(Paths.PluginPath, subFolder);
			if (!Directory.Exists(path))
			{
				if (!string.IsNullOrEmpty(subFolder))
				{
					Instance.logger.LogWarning((object)("Requested directory at BepInEx/Plugins/" + modFolder + "/" + subFolder + " does not exist!"));
				}
				else
				{
					Instance.logger.LogWarning((object)("Requested directory at BepInEx/Plugins/" + modFolder + " does not exist!"));
					if (!modFolder.Contains("-"))
					{
						Instance.logger.LogWarning((object)"This sound mod might not be compatable with mod managers. You should contact the sound mod's author.");
					}
				}
				flag = false;
			}
			if (!File.Exists(text2))
			{
				Instance.logger.LogWarning((object)("Requested audio file does not exist at path " + text2 + "!"));
				flag = false;
				Instance.logger.LogDebug((object)("Looking for audio file from mod root instead at " + text3 + "..."));
				if (File.Exists(text3))
				{
					Instance.logger.LogDebug((object)("Found audio file at path " + text3 + "!"));
					text2 = text3;
					flag = true;
				}
				else
				{
					Instance.logger.LogWarning((object)("Requested audio file does not exist at mod root path " + text3 + "!"));
				}
			}
			if (Directory.Exists(path2))
			{
				if (!string.IsNullOrEmpty(subFolder))
				{
					Instance.logger.LogWarning((object)("Legacy directory location at BepInEx/Plugins/" + subFolder + " found!"));
				}
				else if (!modFolder.Contains("-"))
				{
					Instance.logger.LogWarning((object)"Legacy directory location at BepInEx/Plugins found!");
				}
			}
			if (File.Exists(text4))
			{
				Instance.logger.LogWarning((object)("Legacy path contains the requested audio file at path " + text4 + "!"));
				text = " legacy ";
				text2 = text4;
				flag = true;
			}
			string[] array = soundName.Split('.');
			if (array[^1].ToLower().Contains("ogg"))
			{
				audioType = AudioType.ogg;
				Instance.logger.LogDebug((object)"File detected as an Ogg Vorbis file!");
			}
			else if (array[^1].ToLower().Contains("mp3"))
			{
				audioType = AudioType.mp3;
				Instance.logger.LogDebug((object)"File detected as a MPEG MP3 file!");
			}
			AudioClip val = null;
			if (flag)
			{
				Instance.logger.LogDebug((object)("Loading AudioClip " + soundName + " from" + text + "path: " + text2));
				switch (audioType)
				{
				case AudioType.wav:
					val = WavUtility.LoadFromDiskToAudioClip(text2);
					break;
				case AudioType.ogg:
					val = OggUtility.LoadFromDiskToAudioClip(text2);
					break;
				case AudioType.mp3:
					val = Mp3Utility.LoadFromDiskToAudioClip(text2);
					break;
				}
				Instance.logger.LogDebug((object)$"Finished loading AudioClip {soundName} with length of {val.length}!");
			}
			else
			{
				Instance.logger.LogWarning((object)("Failed to load AudioClip " + soundName + " from invalid" + text + "path at " + text2 + "!"));
			}
			if (string.IsNullOrEmpty(val.GetName()))
			{
				string empty = string.Empty;
				string[] array2 = new string[0];
				switch (audioType)
				{
				case AudioType.wav:
					empty = soundName.Replace(".wav", "");
					array2 = empty.Split('/');
					if (array2.Length <= 1)
					{
						array2 = empty.Split('\\');
					}
					empty = array2[^1];
					((Object)val).name = empty;
					break;
				case AudioType.ogg:
					empty = soundName.Replace(".ogg", "");
					array2 = empty.Split('/');
					if (array2.Length <= 1)
					{
						array2 = empty.Split('\\');
					}
					empty = array2[^1];
					((Object)val).name = empty;
					break;
				case AudioType.mp3:
					empty = soundName.Replace(".mp3", "");
					array2 = empty.Split('/');
					if (array2.Length <= 1)
					{
						array2 = empty.Split('\\');
					}
					empty = array2[^1];
					((Object)val).name = empty;
					break;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				clipTypes.Add(val.GetName(), audioType);
			}
			return val;
		}

		public static AudioClip GetAudioClip(string modFolder, string soundName, AudioType audioType)
		{
			return GetAudioClip(modFolder, string.Empty, soundName, audioType);
		}

		public static AudioClip GetAudioClip(string modFolder, string subFolder, string soundName, AudioType audioType)
		{
			bool flag = true;
			string text = " ";
			string text2 = Path.Combine(Paths.PluginPath, modFolder, subFolder, soundName);
			string text3 = Path.Combine(Paths.PluginPath, modFolder, soundName);
			string path = Path.Combine(Paths.PluginPath, modFolder, subFolder);
			string text4 = Path.Combine(Paths.PluginPath, subFolder, soundName);
			string path2 = Path.Combine(Paths.PluginPath, subFolder);
			if (!Directory.Exists(path))
			{
				if (!string.IsNullOrEmpty(subFolder))
				{
					Instance.logger.LogWarning((object)("Requested directory at BepInEx/Plugins/" + modFolder + "/" + subFolder + " does not exist!"));
				}
				else
				{
					Instance.logger.LogWarning((object)("Requested directory at BepInEx/Plugins/" + modFolder + " does not exist!"));
					if (!modFolder.Contains("-"))
					{
						Instance.logger.LogWarning((object)"This sound mod might not be compatable with mod managers. You should contact the sound mod's author.");
					}
				}
				flag = false;
			}
			if (!File.Exists(text2))
			{
				Instance.logger.LogWarning((object)("Requested audio file does not exist at path " + text2 + "!"));
				flag = false;
				Instance.logger.LogDebug((object)("Looking for audio file from mod root instead at " + text3 + "..."));
				if (File.Exists(text3))
				{
					Instance.logger.LogDebug((object)("Found audio file at path " + text3 + "!"));
					text2 = text3;
					flag = true;
				}
				else
				{
					Instance.logger.LogWarning((object)("Requested audio file does not exist at mod root path " + text3 + "!"));
				}
			}
			if (Directory.Exists(path2))
			{
				if (!string.IsNullOrEmpty(subFolder))
				{
					Instance.logger.LogWarning((object)("Legacy directory location at BepInEx/Plugins/" + subFolder + " found!"));
				}
				else if (!modFolder.Contains("-"))
				{
					Instance.logger.LogWarning((object)"Legacy directory location at BepInEx/Plugins found!");
				}
			}
			if (File.Exists(text4))
			{
				Instance.logger.LogWarning((object)("Legacy path contains the requested audio file at path " + text4 + "!"));
				text = " legacy ";
				text2 = text4;
				flag = true;
			}
			switch (audioType)
			{
			case AudioType.wav:
				Instance.logger.LogDebug((object)"File defined as a WAV file!");
				break;
			case AudioType.ogg:
				Instance.logger.LogDebug((object)"File defined as an Ogg Vorbis file!");
				break;
			case AudioType.mp3:
				Instance.logger.LogDebug((object)"File defined as a MPEG MP3 file!");
				break;
			}
			AudioClip val = null;
			if (flag)
			{
				Instance.logger.LogDebug((object)("Loading AudioClip " + soundName + " from" + text + "path: " + text2));
				switch (audioType)
				{
				case AudioType.wav:
					val = WavUtility.LoadFromDiskToAudioClip(text2);
					break;
				case AudioType.ogg:
					val = OggUtility.LoadFromDiskToAudioClip(text2);
					break;
				case AudioType.mp3:
					val = Mp3Utility.LoadFromDiskToAudioClip(text2);
					break;
				}
				Instance.logger.LogDebug((object)$"Finished loading AudioClip {soundName} with length of {val.length}!");
			}
			else
			{
				Instance.logger.LogWarning((object)("Failed to load AudioClip " + soundName + " from invalid" + text + "path at " + text2 + "!"));
			}
			if (string.IsNullOrEmpty(val.GetName()))
			{
				string empty = string.Empty;
				string[] array = new string[0];
				switch (audioType)
				{
				case AudioType.wav:
					empty = soundName.Replace(".wav", "");
					array = empty.Split('/');
					if (array.Length <= 1)
					{
						array = empty.Split('\\');
					}
					empty = array[^1];
					((Object)val).name = empty;
					break;
				case AudioType.ogg:
					empty = soundName.Replace(".ogg", "");
					array = empty.Split('/');
					if (array.Length <= 1)
					{
						array = empty.Split('\\');
					}
					empty = array[^1];
					((Object)val).name = empty;
					break;
				case AudioType.mp3:
					empty = soundName.Replace(".mp3", "");
					array = empty.Split('/');
					if (array.Length <= 1)
					{
						array = empty.Split('\\');
					}
					empty = array[^1];
					((Object)val).name = empty;
					break;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				clipTypes.Add(val.GetName(), audioType);
			}
			return val;
		}

		public static void SendNetworkedAudioClip(AudioClip audioClip)
		{
			if (!Instance.configUseNetworking.Value)
			{
				Instance.logger.LogWarning((object)$"Networking disabled! Failed to send {audioClip}!");
				return;
			}
			if ((Object)(object)audioClip == (Object)null)
			{
				Instance.logger.LogWarning((object)$"audioClip variable of SendAudioClip not assigned! Failed to send {audioClip}!");
				return;
			}
			if ((Object)(object)Instance == (Object)null || (Object)(object)GameNetworkManagerPatch.networkHandlerHost == (Object)null || (Object)(object)NetworkHandler.Instance == (Object)null)
			{
				Instance.logger.LogWarning((object)$"Instance of SoundTool not found or networking has not finished initializing. Failed to send {audioClip}! If you're sending things in Awake or in a scene such as the main menu it might be too early, please try some of the other built-in Unity methods and make sure your networked audio runs only after the player setups a networked connection!");
				return;
			}
			string name = audioClip.GetName();
			if (clipTypes.ContainsKey(name))
			{
				if (clipTypes[name] == AudioType.ogg)
				{
					NetworkHandler.Instance.SendAudioClipServerRpc(name, OggUtility.AudioClipToByteArray(audioClip, out var _));
					return;
				}
				if (clipTypes[name] == AudioType.mp3)
				{
					NetworkHandler.Instance.SendAudioClipServerRpc(name, Mp3Utility.AudioClipToByteArray(audioClip, out var _));
					return;
				}
			}
			NetworkHandler.Instance.SendAudioClipServerRpc(name, WavUtility.AudioClipToByteArray(audioClip, out var _));
		}

		public static void RemoveNetworkedAudioClip(AudioClip audioClip)
		{
			RemoveNetworkedAudioClip(audioClip.GetName());
		}

		public static void RemoveNetworkedAudioClip(string audioClip)
		{
			if (!Instance.configUseNetworking.Value)
			{
				Instance.logger.LogWarning((object)("Networking disabled! Failed to remove " + audioClip + "!"));
			}
			else if (string.IsNullOrEmpty(audioClip))
			{
				Instance.logger.LogWarning((object)("audioClip variable of RemoveAudioClip not assigned! Failed to remove " + audioClip + "!"));
			}
			else if ((Object)(object)Instance == (Object)null || (Object)(object)GameNetworkManagerPatch.networkHandlerHost == (Object)null || (Object)(object)NetworkHandler.Instance == (Object)null)
			{
				Instance.logger.LogWarning((object)("Instance of SoundTool not found or networking has not finished initializing. Failed to remove " + audioClip + "! If you're removing things in Awake or in a scene such as the main menu it might be too early, please try some of the other built-in Unity methods and make sure your networked audio runs only after the player setups a networked connection!"));
			}
			else
			{
				NetworkHandler.Instance.RemoveAudioClipServerRpc(audioClip);
			}
		}

		public static void SyncNetworkedAudioClips()
		{
			if (!Instance.configUseNetworking.Value)
			{
				Instance.logger.LogWarning((object)"Networking disabled! Failed to sync audio clips!");
			}
			else if ((Object)(object)Instance == (Object)null || (Object)(object)GameNetworkManagerPatch.networkHandlerHost == (Object)null || (Object)(object)NetworkHandler.Instance == (Object)null)
			{
				Instance.logger.LogWarning((object)"Instance of SoundTool not found or networking has not finished initializing. Failed to sync networked audio! If you're syncing things in Awake or in a scene such as the main menu it might be too early, please try some of the other built-in Unity methods and make sure your networked audio runs only after the player setups a networked connection!");
			}
			else
			{
				NetworkHandler.Instance.SyncAudioClipsServerRpc();
			}
		}

		public static void SendUnityRandomSeed(int seed)
		{
			if (!Instance.configUseNetworking.Value)
			{
				Instance.logger.LogWarning((object)"Networking disabled! Failed to send Unity random seed!");
			}
			else if ((Object)(object)Instance == (Object)null || (Object)(object)GameNetworkManagerPatch.networkHandlerHost == (Object)null || (Object)(object)NetworkHandler.Instance == (Object)null)
			{
				Instance.logger.LogWarning((object)"Instance of SoundTool not found or networking has not finished initializing. Failed to send Unity Random seed! If you're sending the seed in Awake or in a scene such as the main menu it might be too early, please try some of the other built-in Unity methods and make sure your networked methods run only after the player setups a networked connection!");
			}
			else
			{
				NetworkHandler.Instance.SendSeedToClientsServerRpc(seed);
			}
		}
	}
}
namespace LCSoundTool.Utilities
{
	public static class Mp3Utility
	{
		public static byte[] AudioClipToByteArray(AudioClip audioClip, out float[] samples)
		{
			samples = new float[audioClip.samples * audioClip.channels];
			audioClip.GetData(samples, 0);
			byte[] array = new byte[samples.Length * 2];
			int num = 32767;
			for (int i = 0; i < samples.Length; i++)
			{
				short value = (short)(samples[i] * (float)num);
				BitConverter.GetBytes(value).CopyTo(array, i * 2);
			}
			return array;
		}

		public static AudioClip ByteArrayToAudioClip(byte[] byteArray, string clipName)
		{
			int num = 16;
			int num2 = num / 8;
			AudioClip val = AudioClip.Create(clipName, byteArray.Length / num2, 1, 44100, false);
			val.SetData(ConvertByteArrayToFloatArray(byteArray), 0);
			return val;
		}

		private static float[] ConvertByteArrayToFloatArray(byte[] byteArray)
		{
			float[] array = new float[byteArray.Length / 2];
			int num = 32767;
			for (int i = 0; i < array.Length; i++)
			{
				short num2 = BitConverter.ToInt16(byteArray, i * 2);
				array[i] = (float)num2 / (float)num;
			}
			return array;
		}

		public static AudioClip LoadFromDiskToAudioClip(string path)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)13);
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result != 1)
					{
						SoundTool.Instance.logger.LogError((object)("Failed to load MP3 AudioClip from path: " + path + " Full error: " + audioClip.error));
					}
					else
					{
						result = DownloadHandlerAudioClip.GetContent(audioClip);
					}
				}
				catch (Exception ex)
				{
					SoundTool.Instance.logger.LogError((object)(ex.Message + ", " + ex.StackTrace));
				}
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
			return result;
		}
	}
	public static class OggUtility
	{
		public static byte[] AudioClipToByteArray(AudioClip audioClip, out float[] samples)
		{
			samples = new float[audioClip.samples * audioClip.channels];
			audioClip.GetData(samples, 0);
			byte[] array = new byte[samples.Length * 2];
			int num = 32767;
			for (int i = 0; i < samples.Length; i++)
			{
				short value = (short)(samples[i] * (float)num);
				BitConverter.GetBytes(value).CopyTo(array, i * 2);
			}
			return array;
		}

		public static AudioClip ByteArrayToAudioClip(byte[] byteArray, string clipName)
		{
			int num = 16;
			int num2 = num / 8;
			AudioClip val = AudioClip.Create(clipName, byteArray.Length / num2, 1, 44100, false);
			val.SetData(ConvertByteArrayToFloatArray(byteArray), 0);
			return val;
		}

		private static float[] ConvertByteArrayToFloatArray(byte[] byteArray)
		{
			float[] array = new float[byteArray.Length / 2];
			int num = 32767;
			for (int i = 0; i < array.Length; i++)
			{
				short num2 = BitConverter.ToInt16(byteArray, i * 2);
				array[i] = (float)num2 / (float)num;
			}
			return array;
		}

		public static AudioClip LoadFromDiskToAudioClip(string path)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)14);
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result != 1)
					{
						SoundTool.Instance.logger.LogError((object)("Failed to load OGGVORBIS AudioClip from path: " + path + " Full error: " + audioClip.error));
					}
					else
					{
						result = DownloadHandlerAudioClip.GetContent(audioClip);
					}
				}
				catch (Exception ex)
				{
					SoundTool.Instance.logger.LogError((object)(ex.Message + ", " + ex.StackTrace));
				}
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
			return result;
		}
	}
	public static class WavUtility
	{
		public static byte[] AudioClipToByteArray(AudioClip audioClip, out float[] samples)
		{
			samples = new float[audioClip.samples * audioClip.channels];
			audioClip.GetData(samples, 0);
			byte[] array = new byte[samples.Length * 2];
			int num = 32767;
			for (int i = 0; i < samples.Length; i++)
			{
				short value = (short)(samples[i] * (float)num);
				BitConverter.GetBytes(value).CopyTo(array, i * 2);
			}
			return array;
		}

		public static AudioClip ByteArrayToAudioClip(byte[] byteArray, string clipName)
		{
			int num = 16;
			int num2 = num / 8;
			AudioClip val = AudioClip.Create(clipName, byteArray.Length / num2, 1, 44100, false);
			val.SetData(ConvertByteArrayToFloatArray(byteArray), 0);
			return val;
		}

		private static float[] ConvertByteArrayToFloatArray(byte[] byteArray)
		{
			float[] array = new float[byteArray.Length / 2];
			int num = 32767;
			for (int i = 0; i < array.Length; i++)
			{
				short num2 = BitConverter.ToInt16(byteArray, i * 2);
				array[i] = (float)num2 / (float)num;
			}
			return array;
		}

		public static AudioClip LoadFromDiskToAudioClip(string path)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)20);
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result != 1)
					{
						SoundTool.Instance.logger.LogError((object)("Failed to load WAV AudioClip from path: " + path + " Full error: " + audioClip.error));
					}
					else
					{
						result = DownloadHandlerAudioClip.GetContent(audioClip);
					}
				}
				catch (Exception ex)
				{
					SoundTool.Instance.logger.LogError((object)(ex.Message + ", " + ex.StackTrace));
				}
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
			return result;
		}
	}
}
namespace LCSoundTool.Patches
{
	[HarmonyPatch(typeof(AudioSource))]
	internal class AudioSourcePatch
	{
		private static Dictionary<string, AudioClip> originalClips = new Dictionary<string, AudioClip>();

		[HarmonyPatch("Play", new Type[] { })]
		[HarmonyPrefix]
		public static void Play_Patch(AudioSource __instance)
		{
			RunDynamicClipReplacement(__instance);
			DebugPlayMethod(__instance);
		}

		[HarmonyPatch("Play", new Type[] { typeof(ulong) })]
		[HarmonyPrefix]
		public static void Play_UlongPatch(AudioSource __instance)
		{
			RunDynamicClipReplacement(__instance);
			DebugPlayMethod(__instance);
		}

		[HarmonyPatch("Play", new Type[] { typeof(double) })]
		[HarmonyPrefix]
		public static void Play_DoublePatch(AudioSource __instance)
		{
			RunDynamicClipReplacement(__instance);
			DebugPlayMethod(__instance);
		}

		[HarmonyPatch("PlayDelayed", new Type[] { typeof(float) })]
		[HarmonyPrefix]
		public static void PlayDelayed_Patch(AudioSource __instance)
		{
			RunDynamicClipReplacement(__instance);
			DebugPlayDelayedMethod(__instance);
		}

		[HarmonyPatch("PlayClipAtPoint", new Type[]
		{
			typeof(AudioClip),
			typeof(Vector3),
			typeof(float)
		})]
		[HarmonyPrefix]
		public static bool PlayClipAtPoint_Patch(AudioClip clip, Vector3 position, float volume)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("One shot audio");
			val.transform.position = position;
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.clip = clip;
			val2.spatialBlend = 1f;
			val2.volume = volume;
			RunDynamicClipReplacement(val2);
			val2.Play();
			DebugPlayClipAtPointMethod(val2, position);
			Object.Destroy((Object)(object)val, clip.length * ((Time.timeScale < 0.01f) ? 0.01f : Time.timeScale));
			return false;
		}

		[HarmonyPatch("PlayOneShotHelper", new Type[]
		{
			typeof(AudioSource),
			typeof(AudioClip),
			typeof(float)
		})]
		[HarmonyPrefix]
		public static void PlayOneShotHelper_Patch(AudioSource source, ref AudioClip clip, float volumeScale)
		{
			clip = ReplaceClipWithNew(clip);
			DebugPlayOneShotMethod(source, clip);
		}

		private static void DebugPlayMethod(AudioSource instance)
		{
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (SoundTool.debugAudioSources && !SoundTool.indepthDebugging && (Object)(object)instance != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{instance} at {((Component)instance).transform.root} is playing {((Object)instance.clip).name}");
			}
			else if (SoundTool.indepthDebugging && (Object)(object)instance != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{instance} is playing {((Object)instance.clip).name} at");
				Transform val = ((Component)instance).transform;
				while ((Object)(object)val.parent != (Object)null || (Object)(object)val != (Object)(object)((Component)instance).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {val.parent}");
					val = val.parent;
				}
				if ((Object)(object)val == (Object)(object)((Component)instance).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {((Component)instance).transform.root}");
				}
			}
		}

		private static void DebugPlayDelayedMethod(AudioSource instance)
		{
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (SoundTool.debugAudioSources && !SoundTool.indepthDebugging && (Object)(object)instance != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{instance} at {((Component)instance).transform.root} is playing {((Object)instance.clip).name} with delay");
			}
			else if (SoundTool.indepthDebugging && (Object)(object)instance != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{instance} is playing {((Object)instance.clip).name} with delay at");
				Transform val = ((Component)instance).transform;
				while ((Object)(object)val.parent != (Object)null || (Object)(object)val != (Object)(object)((Component)instance).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {val.parent}");
					val = val.parent;
				}
				if ((Object)(object)val == (Object)(object)((Component)instance).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {((Component)instance).transform.root}");
				}
			}
		}

		private static void DebugPlayClipAtPointMethod(AudioSource audioSource, Vector3 position)
		{
			//IL_0065: 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)
			if ((Object)(object)audioSource == (Object)null)
			{
				return;
			}
			if (SoundTool.debugAudioSources && !SoundTool.indepthDebugging && (Object)(object)audioSource != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{audioSource} at {((Component)audioSource).transform.root} is playing {((Object)audioSource.clip).name} at point {position}");
			}
			else if (SoundTool.indepthDebugging && (Object)(object)audioSource != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{audioSource} is playing {((Object)audioSource.clip).name} located at point {position} within ");
				Transform val = ((Component)audioSource).transform;
				while ((Object)(object)val.parent != (Object)null || (Object)(object)val != (Object)(object)((Component)audioSource).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {val.parent}");
					val = val.parent;
				}
				if ((Object)(object)val == (Object)(object)((Component)audioSource).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {((Component)audioSource).transform.root}");
				}
			}
		}

		private static void DebugPlayOneShotMethod(AudioSource source, AudioClip clip)
		{
			if ((Object)(object)source == (Object)null || (Object)(object)clip == (Object)null)
			{
				return;
			}
			if (SoundTool.debugAudioSources && !SoundTool.indepthDebugging && (Object)(object)source != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{source} at {((Component)source).transform.root} is playing one shot {((Object)clip).name}");
			}
			else if (SoundTool.indepthDebugging && (Object)(object)source != (Object)null)
			{
				SoundTool.Instance.logger.LogDebug((object)$"{source} is playing one shot {((Object)clip).name} at");
				Transform val = ((Component)source).transform;
				while ((Object)(object)val.parent != (Object)null || (Object)(object)val != (Object)(object)((Component)source).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {val.parent}");
					val = val.parent;
				}
				if ((Object)(object)val == (Object)(object)((Component)source).transform.root)
				{
					SoundTool.Instance.logger.LogDebug((object)$"--- {((Component)source).transform.root}");
				}
			}
		}

		private static void RunDynamicClipReplacement(AudioSource instance)
		{
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.clip == (Object)null)
			{
				return;
			}
			string name = instance.clip.GetName();
			if (SoundTool.replacedClips.ContainsKey(name))
			{
				if (!originalClips.ContainsKey(name))
				{
					originalClips.Add(name, instance.clip);
				}
				List<RandomAudioClip> list = SoundTool.replacedClips[name];
				float num = 0f;
				foreach (RandomAudioClip item in list)
				{
					num += item.chance;
				}
				float num2 = Random.Range(0f, num);
				{
					foreach (RandomAudioClip item2 in list)
					{
						if (num2 <= item2.chance)
						{
							instance.clip = item2.clip;
							break;
						}
						num2 -= item2.chance;
					}
					return;
				}
			}
			if (originalClips.ContainsKey(name))
			{
				instance.clip = originalClips[name];
				originalClips.Remove(name);
			}
		}

		private static AudioClip ReplaceClipWithNew(AudioClip original)
		{
			if ((Object)(object)original == (Object)null)
			{
				return original;
			}
			string name = original.GetName();
			if (SoundTool.replacedClips.ContainsKey(name))
			{
				if (!originalClips.ContainsKey(name))
				{
					originalClips.Add(name, original);
				}
				List<RandomAudioClip> list = SoundTool.replacedClips[name];
				float num = 0f;
				foreach (RandomAudioClip item in list)
				{
					num += item.chance;
				}
				float num2 = Random.Range(0f, num);
				foreach (RandomAudioClip item2 in list)
				{
					if (num2 <= item2.chance)
					{
						return item2.clip;
					}
					num2 -= item2.chance;
				}
			}
			else if (originalClips.ContainsKey(name))
			{
				AudioClip result = originalClips[name];
				originalClips.Remove(name);
				return result;
			}
			return original;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatch
	{
		public static GameObject networkPrefab;

		public static GameObject networkHandlerHost;

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void Start_Patch()
		{
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				SoundTool.Instance.logger.LogDebug((object)"Loading NetworkHandler prefab...");
				networkPrefab = Assets.bundle.LoadAsset<GameObject>("SoundToolNetworkHandler.prefab");
				if ((Object)(object)networkPrefab == (Object)null)
				{
					SoundTool.Instance.logger.LogError((object)"Failed to load NetworkHandler prefab!");
				}
				if ((Object)(object)networkPrefab != (Object)null)
				{
					NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
					SoundTool.Instance.logger.LogDebug((object)"Registered NetworkHandler prefab!");
				}
				else
				{
					SoundTool.Instance.logger.LogWarning((object)"Failed to registered NetworkHandler prefab! No networking can take place.");
				}
			}
		}

		[HarmonyPatch("StartDisconnect")]
		[HarmonyPostfix]
		private static void StartDisconnect_Patch()
		{
			try
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					SoundTool.Instance.logger.LogDebug((object)"Destroying NetworkHandler prefab!");
					Object.Destroy((Object)(object)networkHandlerHost);
					networkHandlerHost = null;
				}
			}
			catch
			{
				SoundTool.Instance.logger.LogError((object)"Failed to destroy NetworkHandler prefab!");
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void SpawnNetworkHandler()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					SoundTool.Instance.logger.LogDebug((object)"Spawning NetworkHandler prefab!");
					GameNetworkManagerPatch.networkHandlerHost = Object.Instantiate<GameObject>(GameNetworkManagerPatch.networkPrefab, Vector3.zero, Quaternion.identity);
					GameNetworkManagerPatch.networkHandlerHost.GetComponent<NetworkObject>().Spawn(true);
				}
			}
			catch
			{
				SoundTool.Instance.logger.LogError((object)"Failed to spawn NetworkHandler prefab!");
			}
		}
	}
}
namespace LCSoundTool.Networking
{
	public class NetworkHandler : NetworkBehaviour
	{
		public static NetworkHandler Instance { get; private set; }

		public static Dictionary<string, AudioClip> networkedAudioClips { get; private set; }

		public static event Action ClientNetworkedAudioChanged;

		public static event Action HostNetworkedAudioChanged;

		public override void OnNetworkSpawn()
		{
			Debug.Log((object)"LCSoundTool - NetworkHandler created!");
			NetworkHandler.ClientNetworkedAudioChanged = null;
			NetworkHandler.HostNetworkedAudioChanged = null;
			networkedAudioClips = new Dictionary<string, AudioClip>();
			Instance = this;
		}

		[ClientRpc]
		public void ReceiveAudioClipClientRpc(string clipName, byte[] audioData)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2736638642u, val, (RpcDelivery)0);
				bool flag = clipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false);
				}
				bool flag2 = audioData != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(audioData, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2736638642u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			if (!networkedAudioClips.ContainsKey(clipName))
			{
				AudioClip val3 = null;
				if (SoundTool.clipTypes.ContainsKey(clipName))
				{
					if (SoundTool.clipTypes[clipName] == SoundTool.AudioType.ogg)
					{
						val3 = OggUtility.ByteArrayToAudioClip(audioData, clipName);
					}
					else if (SoundTool.clipTypes[clipName] == SoundTool.AudioType.mp3)
					{
						val3 = Mp3Utility.ByteArrayToAudioClip(audioData, clipName);
					}
				}
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = WavUtility.ByteArrayToAudioClip(audioData, clipName);
				}
				networkedAudioClips.Add(clipName, val3);
				NetworkHandler.ClientNetworkedAudioChanged?.Invoke();
			}
			else
			{
				SoundTool.Instance.logger.LogDebug((object)("Sound " + clipName + " already exists for this client! Skipping addition of this sound for this client."));
			}
		}

		[ClientRpc]
		public void RemoveAudioClipClientRpc(string clipName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1355469546u, val, (RpcDelivery)0);
				bool flag = clipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1355469546u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && networkedAudioClips.ContainsKey(clipName))
			{
				networkedAudioClips.Remove(clipName);
				NetworkHandler.ClientNetworkedAudioChanged?.Invoke();
			}
		}

		[ClientRpc]
		public void SyncAudioClipsClientRpc(Strings clipNames)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3300200130u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<Strings>(ref clipNames, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3300200130u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			string[] myStrings = clipNames.MyStrings;
			for (int i = 0; i < myStrings.Length; i++)
			{
				if (!networkedAudioClips.ContainsKey(myStrings[i]))
				{
					SendExistingAudioClipServerRpc(myStrings[i]);
				}
			}
		}

		[ClientRpc]
		public void ReceiveSeedClientRpc(int seed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1556253924u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, seed);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1556253924u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Random.InitState(seed);
					SoundTool.Instance.logger.LogDebug((object)$"Client received a new Unity Random seed of {seed}!");
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SendAudioClipServerRpc(string clipName, byte[] audioData)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(867452943u, val, (RpcDelivery)0);
				bool flag = clipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false);
				}
				bool flag2 = audioData != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
				if (flag2)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe<byte>(audioData, default(ForPrimitives));
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 867452943u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ReceiveAudioClipClientRpc(clipName, audioData);
				NetworkHandler.HostNetworkedAudioChanged?.Invoke();
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void RemoveAudioClipServerRpc(string clipName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3103497155u, val, (RpcDelivery)0);
				bool flag = clipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3103497155u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				RemoveAudioClipClientRpc(clipName);
				NetworkHandler.HostNetworkedAudioChanged?.Invoke();
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SyncAudioClipsServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(178607916u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 178607916u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				Strings clipNames = new Strings(networkedAudioClips.Keys.ToArray());
				if (clipNames.MyStrings.Length < 1)
				{
					SoundTool.Instance.logger.LogDebug((object)"No sounds found in networkedClips. Syncing process cancelled!");
				}
				else
				{
					SyncAudioClipsClientRpc(clipNames);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SendExistingAudioClipServerRpc(string clipName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4006259189u, val, (RpcDelivery)0);
				bool flag = clipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4006259189u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			if (networkedAudioClips.ContainsKey(clipName))
			{
				byte[] array = null;
				if (SoundTool.clipTypes.ContainsKey(clipName))
				{
					if (SoundTool.clipTypes[clipName] == SoundTool.AudioType.ogg)
					{
						array = OggUtility.AudioClipToByteArray(networkedAudioClips[clipName], out var _);
					}
					else if (SoundTool.clipTypes[clipName] == SoundTool.AudioType.mp3)
					{
						array = Mp3Utility.AudioClipToByteArray(networkedAudioClips[clipName], out var _);
					}
				}
				if (array == null)
				{
					array = WavUtility.AudioClipToByteArray(networkedAudioClips[clipName], out var _);
				}
				ReceiveAudioClipClientRpc(clipName, array);
			}
			else
			{
				SoundTool.Instance.logger.LogWarning((object)"Trying to obtain and sync a sound from the host that does not exist in the host's game!");
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SendSeedToClientsServerRpc(int seed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4286510828u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, seed);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4286510828u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && ((NetworkBehaviour)this).IsHost)
				{
					ReceiveSeedClientRpc(seed);
					SoundTool.Instance.logger.LogDebug((object)$"Sending a new Unity random seed of {seed} to all clients...");
				}
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_NetworkHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2736638642u, new RpcReceiveHandler(__rpc_handler_2736638642));
			NetworkManager.__rpc_func_table.Add(1355469546u, new RpcReceiveHandler(__rpc_handler_1355469546));
			NetworkManager.__rpc_func_table.Add(3300200130u, new RpcReceiveHandler(__rpc_handler_3300200130));
			NetworkManager.__rpc_func_table.Add(1556253924u, new RpcReceiveHandler(__rpc_handler_1556253924));
			NetworkManager.__rpc_func_table.Add(867452943u, new RpcReceiveHandler(__rpc_handler_867452943));
			NetworkManager.__rpc_func_table.Add(3103497155u, new RpcReceiveHandler(__rpc_handler_3103497155));
			NetworkManager.__rpc_func_table.Add(178607916u, new RpcReceiveHandler(__rpc_handler_178607916));
			NetworkManager.__rpc_func_table.Add(4006259189u, new RpcReceiveHandler(__rpc_handler_4006259189));
			NetworkManager.__rpc_func_table.Add(4286510828u, new RpcReceiveHandler(__rpc_handler_4286510828));
		}

		private static void __rpc_handler_2736638642(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string clipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false);
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				byte[] audioData = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref audioData, default(ForPrimitives));
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).ReceiveAudioClipClientRpc(clipName, audioData);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1355469546(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string clipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).RemoveAudioClipClientRpc(clipName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3300200130(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Strings clipNames = default(Strings);
				((FastBufferReader)(ref reader)).ReadValueSafe<Strings>(ref clipNames, default(ForNetworkSerializable));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).SyncAudioClipsClientRpc(clipNames);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1556253924(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int seed = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref seed);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).ReceiveSeedClientRpc(seed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_867452943(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string clipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false);
				}
				bool flag2 = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives));
				byte[] audioData = null;
				if (flag2)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref audioData, default(ForPrimitives));
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SendAudioClipServerRpc(clipName, audioData);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3103497155(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string clipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).RemoveAudioClipServerRpc(clipName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_178607916(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SyncAudioClipsServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4006259189(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string clipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SendExistingAudioClipServerRpc(clipName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4286510828(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int seed = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref seed);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SendSeedToClientsServerRpc(seed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "NetworkHandler";
		}
	}
	public struct Strings : INetworkSerializable
	{
		private string[] myStrings;

		public string[] MyStrings
		{
			get
			{
				return myStrings;
			}
			set
			{
				myStrings = value;
			}
		}

		public Strings(string[] myStrings)
		{
			this.myStrings = myStrings;
		}

		public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (serializer.IsWriter)
			{
				FastBufferWriter fastBufferWriter = serializer.GetFastBufferWriter();
				int num = myStrings.Length;
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				for (int i = 0; i < myStrings.Length; i++)
				{
					((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe(myStrings[i], false);
				}
			}
			if (serializer.IsReader)
			{
				FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
				int num2 = default(int);
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
				myStrings = new string[num2];
				for (int j = 0; j < num2; j++)
				{
					((FastBufferReader)(ref fastBufferReader)).ReadValueSafe(ref myStrings[j], false);
				}
			}
		}
	}
}
namespace LCSoundTool.Resources
{
	public static class Assets
	{
		internal static AssetBundle bundle;
	}
}

BepInEx/plugins/MaskedEnemyRework.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using MaskedEnemyRework.Patches;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("MaskedEnemyRework")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("MaskedEnemyRework")]
[assembly: AssemblyTitle("MaskedEnemyRework")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MaskedEnemyRework
{
	[BepInPlugin("MaskedEnemyRework", "MaskedEnemyRework", "2.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("MaskedEnemyRework");

		private static Plugin Instance;

		internal ManualLogSource logger;

		private ConfigEntry<bool> RemoveMasksConfig;

		private ConfigEntry<bool> RemoveZombieArmsConfig;

		private ConfigEntry<bool> UseSpawnRarityConfig;

		private ConfigEntry<int> SpawnRarityConfig;

		private ConfigEntry<bool> CanSpawnOutsideConfig;

		private ConfigEntry<int> MaxSpawnCountConfig;

		private ConfigEntry<bool> ZombieApocalypeModeConfig;

		private ConfigEntry<int> ZombieApocalypeRandomChanceConfig;

		private ConfigEntry<float> InsideEnemySpawnCurveConfig;

		private ConfigEntry<float> MiddayInsideEnemySpawnCurveConfig;

		private ConfigEntry<float> StartOutsideEnemySpawnCurveConfig;

		private ConfigEntry<float> MidOutsideEnemySpawnCurveConfig;

		private ConfigEntry<float> EndOutsideEnemySpawnCurveConfig;

		public static bool RemoveMasks;

		public static bool RemoveZombieArms;

		public static bool UseSpawnRarity;

		public static int SpawnRarity;

		public static bool CanSpawnOutside;

		public static int MaxSpawnCount;

		public static bool ZombieApocalypseMode;

		public static int RandomChanceZombieApocalypse;

		public static float InsideEnemySpawnCurve;

		public static float MiddayInsideEnemySpawnCurve;

		public static float StartOutsideEnemySpawnCurve;

		public static float MidOutsideEnemySpawnCurve;

		public static float EndOutsideEnemySpawnCurve;

		public static int PlayerCount;

		public static SpawnableEnemyWithRarity maskedPrefab;

		public static SpawnableEnemyWithRarity flowerPrefab;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			RemoveMasksConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Remove Mask From Masked Enemy", true, "Whether or not the Masked Enemy has a mask on.");
			RemoveZombieArmsConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Remove Zombie Arms", true, "Remove the animation where the Masked raise arms like a zombie.");
			UseSpawnRarityConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Use Spawn Rarity", false, "Use custom spawn rate from config. I would recommend leaving this false, as the mod already bumps up the spawn chances significantly. (To the same as bracken)");
			SpawnRarityConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Spawn Rarity", 15, "The rarity for the Masked Enemy to spawn. The higher the number, the more likely to spawn. Can go to 1000000000, any higher will break. Use Spawn Rarity must be set to True");
			CanSpawnOutsideConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allow Masked To Spawn Outside", false, "Whether the Masked Enemy can spawn outside the building");
			MaxSpawnCountConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Number of Masked", 2, "Max Number of possible mimics to spawn in one level");
			ZombieApocalypeModeConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Apocalypse Mode", "Zombie Apocalype Mode", false, "Only spawns Masked! Make sure to crank up the Max Spawn Count in this config! Would also recommend bringing a gun (mod), a shovel works fine too though.... This mode does not play nice with other mods that affect spawn rates. Disable those before playing for best results");
			ZombieApocalypeRandomChanceConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Zombie Apocalypse Mode", "Random Zombie Apocalype Mode", -1, "[Must Be Whole Number] The percent chance from 1 to 100 that a day could contain a zombie apocalypse. Put at -1 to never have the chance arise and don't have Only Spawn Masked turned on");
			InsideEnemySpawnCurveConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Apocalypse Mode", "StartOfDay Inside Masked Spawn Curve", 0.1f, "Spawn curve for masked inside, start of the day. Crank this way up for immediate action. More info in the readme");
			MiddayInsideEnemySpawnCurveConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Apocalypse Mode", "Midday Inside Masked Spawn Curve", 500f, "Spawn curve for masked inside, midday.");
			StartOutsideEnemySpawnCurveConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Apocalypse Mode", "StartOfDay Masked Outside Spawn Curve", -30f, "Spawn curve for outside masked, start of the day.");
			MidOutsideEnemySpawnCurveConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Apocalypse Mode", "Midday Outside Masked Spawn Curve", -30f, "Spawn curve for outside masked, midday.");
			EndOutsideEnemySpawnCurveConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Apocalypse Mode", "EOD Outside Masked Spawn Curve", 10f, "Spawn curve for outside masked, end of day");
			RemoveMasks = RemoveMasksConfig.Value;
			RemoveZombieArms = RemoveZombieArmsConfig.Value;
			UseSpawnRarity = UseSpawnRarityConfig.Value;
			CanSpawnOutside = CanSpawnOutsideConfig.Value;
			MaxSpawnCount = MaxSpawnCountConfig.Value;
			SpawnRarity = SpawnRarityConfig.Value;
			ZombieApocalypseMode = ZombieApocalypeModeConfig.Value;
			InsideEnemySpawnCurve = InsideEnemySpawnCurveConfig.Value;
			MiddayInsideEnemySpawnCurve = MiddayInsideEnemySpawnCurveConfig.Value;
			StartOutsideEnemySpawnCurve = StartOutsideEnemySpawnCurveConfig.Value;
			MidOutsideEnemySpawnCurve = MaxSpawnCountConfig.Value;
			EndOutsideEnemySpawnCurve = EndOutsideEnemySpawnCurveConfig.Value;
			RandomChanceZombieApocalypse = ZombieApocalypeRandomChanceConfig.Value;
			logger = Logger.CreateLogSource("MaskedEnemyRework");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MaskedEnemyRework is loaded! Woohoo!");
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(GetMaskedPrefabForLaterUse));
			harmony.PatchAll(typeof(MaskedVisualRework));
			harmony.PatchAll(typeof(MaskedSpawnSettings));
			harmony.PatchAll(typeof(RemoveZombieArms));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MaskedEnemyRework";

		public const string PLUGIN_NAME = "MaskedEnemyRework";

		public const string PLUGIN_VERSION = "2.0.0";
	}
}
namespace MaskedEnemyRework.Patches
{
	[HarmonyPatch(typeof(Terminal))]
	internal class GetMaskedPrefabForLaterUse
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void SavesPrefabForLaterUse(ref SelectableLevel[] ___moonsCatalogueList)
		{
			ManualLogSource val = Logger.CreateLogSource("MaskedEnemyRework");
			SelectableLevel[] array = ___moonsCatalogueList;
			foreach (SelectableLevel val2 in array)
			{
				foreach (SpawnableEnemyWithRarity enemy in val2.Enemies)
				{
					if (enemy.enemyType.enemyName == "Masked")
					{
						val.LogInfo((object)"Found Masked!");
						Plugin.maskedPrefab = enemy;
					}
					else if (enemy.enemyType.enemyName == "Flowerman")
					{
						Plugin.flowerPrefab = enemy;
						val.LogInfo((object)"Found Flowerman!");
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class MaskedSpawnSettings
	{
		[HarmonyPatch("BeginEnemySpawning")]
		[HarmonyPrefix]
		private static void UpdateSpawnRates(ref SelectableLevel ___currentLevel)
		{
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			//IL_028b: 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_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Expected O, but got Unknown
			ManualLogSource val = Logger.CreateLogSource("MaskedEnemyRework");
			val.LogInfo((object)"Starting Round Manager");
			SpawnableEnemyWithRarity maskedPrefab = Plugin.maskedPrefab;
			SpawnableEnemyWithRarity flowerPrefab = Plugin.flowerPrefab;
			SelectableLevel obj = ___currentLevel;
			obj.maxEnemyPowerCount += maskedPrefab.enemyType.MaxCount;
			SelectableLevel obj2 = ___currentLevel;
			obj2.maxDaytimeEnemyPowerCount += maskedPrefab.enemyType.MaxCount;
			SelectableLevel obj3 = ___currentLevel;
			obj3.maxOutsideEnemyPowerCount += maskedPrefab.enemyType.MaxCount;
			List<SpawnableEnemyWithRarity> enemies = ___currentLevel.Enemies;
			for (int i = 0; i < ___currentLevel.Enemies.Count; i++)
			{
				SpawnableEnemyWithRarity val2 = ___currentLevel.Enemies[i];
				if (val2.enemyType.enemyName == "Masked")
				{
					enemies.Remove(val2);
				}
			}
			___currentLevel.Enemies = enemies;
			maskedPrefab.enemyType.PowerLevel = 1;
			maskedPrefab.enemyType.probabilityCurve = flowerPrefab.enemyType.probabilityCurve;
			if (Plugin.UseSpawnRarity)
			{
				maskedPrefab.rarity = Plugin.SpawnRarity;
			}
			else
			{
				maskedPrefab.rarity = flowerPrefab.rarity;
			}
			maskedPrefab.enemyType.MaxCount = Plugin.MaxSpawnCount;
			maskedPrefab.enemyType.isOutsideEnemy = Plugin.CanSpawnOutside;
			int num = 0;
			num = ((StartOfRound.Instance.randomMapSeed.ToString().Length >= 3) ? int.Parse(StartOfRound.Instance.randomMapSeed.ToString().Substring(1, 2)) : 0);
			val.LogInfo((object)("Map seed " + num + " random chance " + Plugin.RandomChanceZombieApocalypse));
			num = Mathf.Clamp(num, 0, 100);
			if (Plugin.ZombieApocalypseMode || (num <= Plugin.RandomChanceZombieApocalypse && Plugin.RandomChanceZombieApocalypse >= 0))
			{
				val.LogInfo((object)"ZOMBIE APOCALYPSE");
				___currentLevel.enemySpawnChanceThroughoutDay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
				{
					new Keyframe(0f, Plugin.InsideEnemySpawnCurve),
					new Keyframe(0.5f, Plugin.MiddayInsideEnemySpawnCurve)
				});
				___currentLevel.daytimeEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
				{
					new Keyframe(0f, 7f),
					new Keyframe(0.5f, 7f)
				});
				___currentLevel.outsideEnemySpawnChanceThroughDay = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
				{
					new Keyframe(0f, Plugin.StartOutsideEnemySpawnCurve),
					new Keyframe(20f, Plugin.MidOutsideEnemySpawnCurve),
					new Keyframe(21f, Plugin.EndOutsideEnemySpawnCurve)
				});
				maskedPrefab.enemyType.isOutsideEnemy = true;
				maskedPrefab.rarity = 1000000000;
				___currentLevel.OutsideEnemies.Clear();
				___currentLevel.DaytimeEnemies.Clear();
				___currentLevel.DaytimeEnemies.Add(maskedPrefab);
				___currentLevel.OutsideEnemies.Add(maskedPrefab);
				foreach (SpawnableEnemyWithRarity enemy in ___currentLevel.Enemies)
				{
					enemy.rarity = 0;
				}
			}
			else
			{
				val.LogInfo((object)"no zombies :(");
			}
			___currentLevel.Enemies.Add(maskedPrefab);
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal class MaskedVisualRework
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void ReformVisuals(ref MaskedPlayerEnemy __instance)
		{
			ManualLogSource val = Logger.CreateLogSource("MaskedEnemyRework");
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			int num = StartOfRound.Instance.ClientPlayerList.Count;
			if (num == 0)
			{
				num = Random.Range(0, 2);
				val.LogInfo((object)"Player count was zero");
			}
			int num2 = StartOfRound.Instance.randomMapSeed % num;
			val.LogInfo((object)("player count" + num));
			val.LogInfo((object)("player index" + num2));
			num2 = Mathf.Clamp(num2, 0, num);
			PlayerControllerB val2 = allPlayerScripts[num2];
			__instance.mimickingPlayer = val2;
			__instance.SetSuit(val2.currentSuitID);
			if (Plugin.RemoveMasks)
			{
				((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/spine.004/HeadMaskComedy")).gameObject.SetActive(false);
				((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/spine.004/HeadMaskTragedy")).gameObject.SetActive(false);
			}
		}
	}
	internal class RemoveZombieArms
	{
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "SetHandsOutClientRpc")]
		[HarmonyPrefix]
		private static void RemoveArms(ref bool setOut)
		{
			if (Plugin.RemoveZombieArms)
			{
				setOut = false;
			}
		}
	}
}

BepInEx/plugins/MoreShipUpgrades/MoreShipUpgrades.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using MoreShipUpgrades.Managers;
using MoreShipUpgrades.Misc;
using MoreShipUpgrades.UpgradeComponents;
using Newtonsoft.Json;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace MoreShipUpgrades
{
	[BepInPlugin("com.malco.lethalcompany.moreshipupgrades", "More Ship Upgrades", "2.8.0")]
	[BepInDependency("evaisa.lethallib", "0.6.0")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("com.malco.lethalcompany.moreshipupgrades");

		public static Plugin instance;

		public static ManualLogSource mls;

		private AudioClip itemBreak;

		private AudioClip buttonPressed;

		private AudioClip error;

		public static PluginConfig cfg { get; private set; }

		private void Awake()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			cfg = new PluginConfig(((BaseUnityPlugin)this).Config);
			cfg.InitBindings();
			mls = Logger.CreateLogSource("More Ship Upgrades");
			instance = this;
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "shipupgrades");
			AssetBundle bundle = AssetBundle.LoadFromFile(text);
			GameObject val = new GameObject("UpgradeBus");
			val.AddComponent<UpgradeBus>();
			UpgradeBus.instance.version = "2.8.0";
			UpgradeBus.instance.UpgradeAssets = bundle;
			UpgradeBus.instance.internNames = AssetBundleHandler.GetInfoFromJSON("InternNames").Split(",");
			UpgradeBus.instance.internInterests = AssetBundleHandler.GetInfoFromJSON("InternInterests").Split(",");
			SetupModStore(ref bundle);
			SetupIntroScreen(ref bundle);
			SetupItems();
			SetupPerks();
			harmony.PatchAll();
			mls.LogDebug((object)"LGU has been patched");
		}

		public void sendModInfo()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Value.Metadata.GUID.Contains("ModSync"))
				{
					try
					{
						List<string> list = new List<string> { "malco", "LateGameUpgrades" };
						((Component)pluginInfo.Value.Instance).BroadcastMessage("getModInfo", (object)list, (SendMessageOptions)1);
						break;
					}
					catch (Exception)
					{
						mls.LogDebug((object)"Failed to send info to ModSync, go yell at Minx");
						break;
					}
				}
			}
		}

		private void SetupModStore(ref AssetBundle bundle)
		{
			GameObject val = AssetBundleHandler.TryLoadGameObjectAsset(ref bundle, "Assets/ShipUpgrades/LGUStore.prefab");
			if (!((Object)(object)val == (Object)null))
			{
				val.AddComponent<LGUStore>();
				NetworkPrefabs.RegisterNetworkPrefab(val);
				UpgradeBus.instance.modStorePrefab = val;
			}
		}

		private void SetupIntroScreen(ref AssetBundle bundle)
		{
			UpgradeBus.instance.introScreen = AssetBundleHandler.TryLoadGameObjectAsset(ref bundle, "Assets/ShipUpgrades/IntroScreen.prefab");
			if ((Object)(object)UpgradeBus.instance.introScreen != (Object)null)
			{
				UpgradeBus.instance.introScreen.AddComponent<IntroScreenScript>();
			}
		}

		private void SetupItems()
		{
			SetupTeleporterButtons();
			SetupNightVision();
			SetupMedkit();
			SetupPeeper();
			SetupSamples();
			SetupDivingKit(ref UpgradeBus.instance.UpgradeAssets);
		}

		private void SetupSamples()
		{
			foreach (string key in AssetBundleHandler.samplePaths.Keys)
			{
				Item itemObject = AssetBundleHandler.GetItemObject(key);
				SampleItem sampleItem = itemObject.spawnPrefab.AddComponent<SampleItem>();
				((GrabbableObject)sampleItem).grabbable = true;
				((GrabbableObject)sampleItem).grabbableToEnemies = true;
				((GrabbableObject)sampleItem).itemProperties = itemObject;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				UpgradeBus.instance.samplePrefabs.Add(key, itemObject.spawnPrefab);
			}
		}

		private void SetupTeleporterButtons()
		{
			itemBreak = AssetBundleHandler.GetAudioClip("Break");
			error = AssetBundleHandler.GetAudioClip("Error");
			buttonPressed = AssetBundleHandler.GetAudioClip("Button Press");
			if (!((Object)(object)itemBreak == (Object)null) && !((Object)(object)error == (Object)null) && !((Object)(object)buttonPressed == (Object)null))
			{
				SetupRegularTeleporterButton();
				SetupAdvancedTeleporterButton();
			}
		}

		private void SetupRegularTeleporterButton()
		{
			Item itemObject = AssetBundleHandler.GetItemObject("Portable Tele");
			if (!((Object)(object)itemObject == (Object)null))
			{
				itemObject.itemName = "Portable Tele";
				itemObject.itemId = 492012;
				TPButtonScript tPButtonScript = itemObject.spawnPrefab.AddComponent<TPButtonScript>();
				((GrabbableObject)tPButtonScript).itemProperties = itemObject;
				((GrabbableObject)tPButtonScript).grabbable = true;
				((GrabbableObject)tPButtonScript).grabbableToEnemies = true;
				tPButtonScript.ItemBreak = itemBreak;
				((GrabbableObject)tPButtonScript).useCooldown = 2f;
				tPButtonScript.error = error;
				tPButtonScript.buttonPress = buttonPressed;
				itemObject.creditsWorth = cfg.WEAK_TELE_PRICE;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				if (cfg.WEAK_TELE_ENABLED)
				{
					TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
					val.displayText = string.Format(AssetBundleHandler.GetInfoFromJSON("Portable Tele"), (int)(cfg.CHANCE_TO_BREAK * 100f));
					Items.RegisterShopItem(itemObject, (TerminalNode)null, (TerminalNode)null, val, itemObject.creditsWorth);
				}
			}
		}

		private void SetupAdvancedTeleporterButton()
		{
			Item itemObject = AssetBundleHandler.GetItemObject("Advanced Portable Tele");
			if (!((Object)(object)itemObject == (Object)null))
			{
				itemObject.creditsWorth = cfg.ADVANCED_TELE_PRICE;
				itemObject.itemName = "Advanced Portable Tele";
				itemObject.itemId = 492013;
				AdvTPButtonScript advTPButtonScript = itemObject.spawnPrefab.AddComponent<AdvTPButtonScript>();
				((GrabbableObject)advTPButtonScript).itemProperties = itemObject;
				((GrabbableObject)advTPButtonScript).grabbable = true;
				((GrabbableObject)advTPButtonScript).useCooldown = 2f;
				((GrabbableObject)advTPButtonScript).grabbableToEnemies = true;
				advTPButtonScript.ItemBreak = itemBreak;
				advTPButtonScript.error = error;
				advTPButtonScript.buttonPress = buttonPressed;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				if (cfg.ADVANCED_TELE_ENABLED)
				{
					TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
					val.displayText = string.Format(AssetBundleHandler.GetInfoFromJSON("Advanced Portable Tele"), (int)(cfg.ADV_CHANCE_TO_BREAK * 100f));
					Items.RegisterShopItem(itemObject, (TerminalNode)null, (TerminalNode)null, val, itemObject.creditsWorth);
				}
			}
		}

		private void SetupNightVision()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Item itemObject = AssetBundleHandler.GetItemObject("Night Vision");
			if (!((Object)(object)itemObject == (Object)null))
			{
				itemObject.creditsWorth = cfg.NIGHT_VISION_PRICE;
				itemObject.spawnPrefab.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
				itemObject.itemId = 492014;
				NightVisionItemScript nightVisionItemScript = itemObject.spawnPrefab.AddComponent<NightVisionItemScript>();
				((GrabbableObject)nightVisionItemScript).itemProperties = itemObject;
				((GrabbableObject)nightVisionItemScript).grabbable = true;
				((GrabbableObject)nightVisionItemScript).useCooldown = 2f;
				((GrabbableObject)nightVisionItemScript).grabbableToEnemies = true;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				UpgradeBus.instance.nightVisionPrefab = itemObject.spawnPrefab;
				if (cfg.NIGHT_VISION_ENABLED)
				{
					TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
					string arg = ((cfg.NIGHT_VISION_INDIVIDUAL || UpgradeBus.instance.cfg.SHARED_UPGRADES) ? "one" : "all");
					string arg2 = (cfg.LOSE_NIGHT_VIS_ON_DEATH ? "be" : "not be");
					val.displayText = string.Format(AssetBundleHandler.GetInfoFromJSON("Night Vision"), arg, arg2);
					Items.RegisterShopItem(itemObject, (TerminalNode)null, (TerminalNode)null, val, itemObject.creditsWorth);
				}
			}
		}

		private void SetupDivingKit(ref AssetBundle bundle)
		{
			Item val = AssetBundleHandler.TryLoadItemAsset(ref bundle, "Assets/ShipUpgrades/DivingKitItem.asset");
			if (!((Object)(object)val == (Object)null))
			{
				val.creditsWorth = cfg.DIVEKIT_PRICE;
				val.twoHanded = cfg.DIVEKIT_TWO_HANDED;
				val.weight = cfg.DIVEKIT_WEIGHT;
				val.itemSpawnsOnGround = true;
				DivingKitScript divingKitScript = val.spawnPrefab.AddComponent<DivingKitScript>();
				((GrabbableObject)divingKitScript).itemProperties = val;
				((GrabbableObject)divingKitScript).grabbable = true;
				((GrabbableObject)divingKitScript).grabbableToEnemies = true;
				NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
				if (cfg.DIVEKIT_ENABLED)
				{
					TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>();
					string arg = (cfg.DIVEKIT_TWO_HANDED ? "two" : "one");
					val2.displayText = $"DIVING KIT - ${cfg.DIVEKIT_PRICE}\n\nBreath underwater.\nWeights {Mathf.RoundToInt((val.weight - 1f) * 100f)} lbs and is {arg} handed.\n\n";
					Items.RegisterShopItem(val, (TerminalNode)null, (TerminalNode)null, val2, val.creditsWorth);
				}
			}
		}

		private void SetupMedkit()
		{
			Item itemObject = AssetBundleHandler.GetItemObject("Medkit");
			if (!((Object)(object)itemObject == (Object)null))
			{
				itemObject.creditsWorth = cfg.MEDKIT_PRICE;
				itemObject.itemSpawnsOnGround = true;
				itemObject.itemId = 492016;
				MedkitScript medkitScript = itemObject.spawnPrefab.AddComponent<MedkitScript>();
				((GrabbableObject)medkitScript).itemProperties = itemObject;
				((GrabbableObject)medkitScript).grabbable = true;
				((GrabbableObject)medkitScript).useCooldown = 2f;
				((GrabbableObject)medkitScript).grabbableToEnemies = true;
				medkitScript.error = error;
				medkitScript.use = buttonPressed;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				if (cfg.MEDKIT_ENABLED)
				{
					TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
					val.displayText = $"MEDKIT - ${cfg.MEDKIT_PRICE}\n\nLeft click to heal yourself for {cfg.MEDKIT_HEAL_VALUE} health.\nCan be used {cfg.MEDKIT_USES} times.\n";
					Items.RegisterShopItem(itemObject, (TerminalNode)null, (TerminalNode)null, val, itemObject.creditsWorth);
				}
			}
		}

		private void SetupPeeper()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Item itemObject = AssetBundleHandler.GetItemObject("Peeper");
			if (!((Object)(object)itemObject == (Object)null))
			{
				itemObject.creditsWorth = cfg.PEEPER_PRICE;
				itemObject.twoHanded = false;
				itemObject.itemId = 492015;
				itemObject.twoHandedAnimation = false;
				itemObject.spawnPrefab.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
				coilHeadItem coilHeadItem = itemObject.spawnPrefab.AddComponent<coilHeadItem>();
				((GrabbableObject)coilHeadItem).itemProperties = itemObject;
				((GrabbableObject)coilHeadItem).grabbable = true;
				((GrabbableObject)coilHeadItem).grabbableToEnemies = true;
				NetworkPrefabs.RegisterNetworkPrefab(itemObject.spawnPrefab);
				if (cfg.PEEPER_ENABLED)
				{
					TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
					val.displayText = "Looks at coil heads, don't lose it\n";
					Items.RegisterShopItem(itemObject, (TerminalNode)null, (TerminalNode)null, val, itemObject.creditsWorth);
				}
			}
		}

		private void SetupPerks()
		{
			SetupBeekeeper();
			SetupProteinPowder();
			SetupBiggerLungs();
			SetupRunningShoes();
			SetupStrongLegs();
			SetupMalwareBroadcaster();
			SetupNightVisionBattery();
			SetupDiscombobulator();
			SetupBetterScanner();
			SetupWalkieGPS();
			SetupBackMuscles();
			SetupInterns();
			SetupPager();
			SetupLightningRod();
			SetupLocksmith();
			SetupPlayerHealth();
			SetupHunter();
		}

		private void SetupBeekeeper()
		{
			SetupGenericPerk<beekeeperScript>(beekeeperScript.UPGRADE_NAME);
		}

		private void SetupHunter()
		{
			SetupGenericPerk<hunterScript>(hunterScript.UPGRADE_NAME);
		}

		private void SetupProteinPowder()
		{
			SetupGenericPerk<proteinPowderScript>(proteinPowderScript.UPGRADE_NAME);
		}

		private void SetupBiggerLungs()
		{
			SetupGenericPerk<biggerLungScript>(biggerLungScript.UPGRADE_NAME);
		}

		private void SetupRunningShoes()
		{
			SetupGenericPerk<runningShoeScript>(runningShoeScript.UPGRADE_NAME);
		}

		private void SetupStrongLegs()
		{
			SetupGenericPerk<strongLegsScript>(strongLegsScript.UPGRADE_NAME);
		}

		private void SetupMalwareBroadcaster()
		{
			SetupGenericPerk<trapDestroyerScript>(trapDestroyerScript.UPGRADE_NAME);
		}

		private void SetupNightVisionBattery()
		{
			SetupGenericPerk<nightVisionScript>(nightVisionScript.UPGRADE_NAME);
		}

		private void SetupDiscombobulator()
		{
			AudioClip audioClip = AssetBundleHandler.GetAudioClip("Flashbang");
			if ((Object)(object)audioClip != (Object)null)
			{
				UpgradeBus.instance.flashNoise = audioClip;
			}
			SetupGenericPerk<terminalFlashScript>(terminalFlashScript.UPGRADE_NAME);
		}

		private void SetupBetterScanner()
		{
			SetupGenericPerk<strongerScannerScript>(strongerScannerScript.UPGRADE_NAME);
		}

		private void SetupWalkieGPS()
		{
			SetupGenericPerk<walkieScript>(walkieScript.UPGRADE_NAME);
		}

		private void SetupBackMuscles()
		{
			SetupGenericPerk<exoskeletonScript>(exoskeletonScript.UPGRADE_NAME);
		}

		private void SetupInterns()
		{
			SetupGenericPerk<defibScript>(defibScript.UPGRADE_NAME);
		}

		private void SetupPager()
		{
			SetupGenericPerk<pagerScript>(pagerScript.UPGRADE_NAME);
		}

		private void SetupLightningRod()
		{
			SetupGenericPerk<lightningRodScript>(lightningRodScript.UPGRADE_NAME);
		}

		private void SetupLocksmith()
		{
			SetupGenericPerk<lockSmithScript>(lockSmithScript.UPGRADE_NAME);
		}

		private void SetupPlayerHealth()
		{
			SetupGenericPerk<playerHealthScript>(playerHealthScript.UPGRADE_NAME);
		}

		private void SetupGenericPerk<T>(string upgradeName) where T : Component
		{
			GameObject perkGameObject = AssetBundleHandler.GetPerkGameObject(upgradeName);
			if (Object.op_Implicit((Object)(object)perkGameObject))
			{
				perkGameObject.AddComponent<T>();
				NetworkPrefabs.RegisterNetworkPrefab(perkGameObject);
			}
		}
	}
}
namespace MoreShipUpgrades.UpgradeComponents
{
	internal class AdvTPButtonScript : GrabbableObject
	{
		public AudioClip ItemBreak;

		public AudioClip error;

		public AudioClip buttonPress;

		private AudioSource audio;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			audio = ((Component)this).GetComponent<AudioSource>();
		}

		public override void DiscardItem()
		{
			base.playerHeldBy.activatingItem = false;
			((GrabbableObject)this).DiscardItem();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!Mouse.current.leftButton.isPressed)
			{
				return;
			}
			audio.PlayOneShot(buttonPress);
			if (!base.itemUsedUp)
			{
				ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>();
				ShipTeleporter val = null;
				ShipTeleporter[] array2 = array;
				foreach (ShipTeleporter val2 in array2)
				{
					if (!val2.isInverseTeleporter)
					{
						val = val2;
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					audio.PlayOneShot(error);
					return;
				}
				int num = -1;
				for (int j = 0; j < StartOfRound.Instance.mapScreen.radarTargets.Count(); j++)
				{
					if ((Object)(object)((Component)StartOfRound.Instance.mapScreen.radarTargets[j].transform).gameObject.GetComponent<PlayerControllerB>() == (Object)(object)base.playerHeldBy)
					{
						num = j;
					}
				}
				if (num == -1)
				{
					StartOfRound.Instance.mapScreen.targetedPlayer = base.playerHeldBy;
					UpgradeBus.instance.TPButtonPressed = true;
					val.PressTeleportButtonOnLocalClient();
				}
				else
				{
					StartOfRound.Instance.mapScreen.SwitchRadarTargetAndSync(num);
					((MonoBehaviour)this).StartCoroutine(WaitToTP(val));
				}
			}
			else
			{
				audio.PlayOneShot(error);
			}
		}

		private IEnumerator WaitToTP(ShipTeleporter tele)
		{
			yield return (object)new WaitForSeconds(0.15f);
			if (UpgradeBus.instance.cfg.ADV_KEEP_ITEMS_ON_TELE)
			{
				ReqUpdateTpDropStatusServerRpc();
			}
			tele.PressTeleportButtonOnLocalClient();
			if (Random.Range(0f, 1f) < UpgradeBus.instance.cfg.ADV_CHANCE_TO_BREAK)
			{
				audio.PlayOneShot(ItemBreak);
				base.itemUsedUp = true;
				HUDManager.Instance.DisplayTip("TELEPORTER BROKE!", "The teleporter button has suffered irreparable damage and destroyed itself!", true, false, "LC_Tip1");
				base.playerHeldBy.DespawnHeldObject();
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void ReqUpdateTpDropStatusServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3988692149u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3988692149u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ChangeTPButtonPressedClientRpc();
				}
			}
		}

		[ClientRpc]
		private void ChangeTPButtonPressedClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2793166939u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2793166939u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					UpgradeBus.instance.TPButtonPressed = true;
				}
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_AdvTPButtonScript()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3988692149u, new RpcReceiveHandler(__rpc_handler_3988692149));
			NetworkManager.__rpc_func_table.Add(2793166939u, new RpcReceiveHandler(__rpc_handler_2793166939));
		}

		private static void __rpc_handler_3988692149(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((AdvTPButtonScript)(object)target).ReqUpdateTpDropStatusServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2793166939(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((AdvTPButtonScript)(object)target).ChangeTPButtonPressedClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "AdvTPButtonScript";
		}
	}
	internal class beekeeperScript : BaseUpgrade
	{
		private new static LGULogger logger = new LGULogger(UPGRADE_NAME);

		public static string UPGRADE_NAME = "Beekeeper";

		public static string PRICES_DEFAULT = "225,280,340";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.beeLevel++;
			if (UpgradeBus.instance.beeLevel == UpgradeBus.instance.cfg.BEEKEEPER_UPGRADE_PRICES.Split(',').Length)
			{
				LGUStore.instance.ToggleIncreaseHivePriceServerRpc();
			}
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.beekeeper = true;
		}

		public override void Register()
		{
			base.Register();
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.beeLevel = 0;
			UpgradeBus.instance.beekeeper = false;
		}

		public static int CalculateBeeDamage(int damageNumber)
		{
			if (!UpgradeBus.instance.beekeeper)
			{
				return damageNumber;
			}
			return Mathf.Clamp((int)((float)damageNumber * (UpgradeBus.instance.cfg.BEEKEEPER_DAMAGE_MULTIPLIER - (float)UpgradeBus.instance.beeLevel * UpgradeBus.instance.cfg.BEEKEEPER_DAMAGE_MULTIPLIER_INCREMENT)), 0, damageNumber);
		}

		public static int GetHiveScrapValue(int originalValue)
		{
			if (!UpgradeBus.instance.increaseHivePrice)
			{
				return originalValue;
			}
			return (int)((float)originalValue * UpgradeBus.instance.cfg.BEEKEEPER_HIVE_VALUE_INCREASE);
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "beekeeperScript";
		}
	}
	internal class biggerLungScript : BaseUpgrade
	{
		private PlayerControllerB localPlayer;

		private new static LGULogger logger = new LGULogger(UPGRADE_NAME);

		public static string UPGRADE_NAME = "Bigger Lungs";

		public static string PRICES_DEFAULT = "350,450,550";

		private static float DEFAULT_SPRINT_TIME = 11f;

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.lungLevel++;
			PlayerControllerB val = GetLocalPlayer();
			val.sprintTime += UpgradeBus.instance.cfg.SPRINT_TIME_INCREMENT;
		}

		public override void load()
		{
			PlayerControllerB val = GetLocalPlayer();
			val.sprintTime = UpgradeBus.instance.cfg.SPRINT_TIME_INCREASE;
			UpgradeBus.instance.biggerLungs = true;
			base.load();
			float num = 0f;
			for (int i = 0; i < UpgradeBus.instance.lungLevel; i++)
			{
				num += UpgradeBus.instance.cfg.SPRINT_TIME_INCREMENT;
			}
			PlayerControllerB obj = localPlayer;
			obj.sprintTime += num;
		}

		public override void Unwind()
		{
			PlayerControllerB val = GetLocalPlayer();
			val.sprintTime = DEFAULT_SPRINT_TIME;
			base.Unwind();
			UpgradeBus.instance.biggerLungs = false;
		}

		public override void Register()
		{
			base.Register();
		}

		private PlayerControllerB GetLocalPlayer()
		{
			if ((Object)(object)localPlayer == (Object)null)
			{
				localPlayer = GameNetworkManager.Instance.localPlayerController;
			}
			return localPlayer;
		}

		public static float ApplyPossibleIncreasedStaminaRegen(float regenValue)
		{
			if (!UpgradeBus.instance.biggerLungs || UpgradeBus.instance.lungLevel < 0)
			{
				return regenValue;
			}
			return regenValue * UpgradeBus.instance.cfg.BIGGER_LUNGS_STAMINA_REGEN_INCREASE;
		}

		public static float ApplyPossibleReducedJumpStaminaCost(float jumpCost)
		{
			if (!UpgradeBus.instance.biggerLungs || UpgradeBus.instance.lungLevel < 1)
			{
				return jumpCost;
			}
			return jumpCost * UpgradeBus.instance.cfg.BIGGER_LUNGS_JUMP_STAMINA_COST_DECREASE;
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "biggerLungScript";
		}
	}
	public class coilHeadItem : GrabbableObject
	{
		private bool Active;

		private bool audioInit;

		private Animator anim;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			anim = ((Component)this).GetComponent<Animator>();
			UpgradeBus.instance.coilHeadItems.Add(this);
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
			if (base.isHeld || base.isHeldByEnemy)
			{
				Active = false;
				anim.SetBool("Grounded", false);
			}
			else
			{
				Active = true;
				anim.SetBool("Grounded", true);
			}
		}

		public bool HasLineOfSightToPosition(Vector3 pos, int range = 60)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!Active)
			{
				return false;
			}
			float num = Vector3.Distance(((Component)this).transform.position, pos);
			return num < (float)range && !Physics.Linecast(((Component)this).transform.position, pos, StartOfRound.Instance.collidersRoomDefaultAndFoliage, (QueryTriggerInteraction)1);
		}

		public static bool HasLineOfSightToPeepers(Vector3 springPosition)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			foreach (coilHeadItem coilHeadItem in UpgradeBus.instance.coilHeadItems)
			{
				if ((Object)(object)coilHeadItem == (Object)null)
				{
					UpgradeBus.instance.coilHeadItems.Remove(coilHeadItem);
				}
				else if (coilHeadItem.HasLineOfSightToPosition(springPosition))
				{
					return true;
				}
			}
			return false;
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "coilHeadItem";
		}
	}
	public class defibScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Interns";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
			UpgradeBus.instance.internScript = this;
		}

		public override void Register()
		{
			base.Register();
		}

		[ServerRpc(RequireOwnership = false)]
		public void ReviveTargetedPlayerServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1556828106u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1556828106u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ReviveTargetedPlayerClientRpc();
					Vector3 position = RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position;
					position = RoundManager.Instance.GetRandomNavMeshPositionInRadiusSpherical(position, 10f, default(NavMeshHit));
					NetworkBehaviourReference netRef = default(NetworkBehaviourReference);
					((NetworkBehaviourReference)(ref netRef))..ctor((NetworkBehaviour)(object)StartOfRound.Instance.mapScreen.targetedPlayer);
					TelePlayerClientRpc(position, netRef);
				}
			}
		}

		[ClientRpc]
		private void TelePlayerClientRpc(Vector3 vector, NetworkBehaviourReference netRef)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(52528808u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref vector);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkBehaviourReference>(ref netRef, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 52528808u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				NetworkBehaviour val3 = default(NetworkBehaviour);
				((NetworkBehaviourReference)(ref netRef)).TryGet(ref val3, (NetworkManager)null);
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)((Component)val3).transform).GetComponent<PlayerControllerB>().TeleportPlayer(vector, false, 0f, false, true);
				}
			}
		}

		[ClientRpc]
		private void ReviveTargetedPlayerClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1174848284u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1174848284u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			PlayerControllerB targetedPlayer = StartOfRound.Instance.mapScreen.targetedPlayer;
			int num = (UpgradeBus.instance.playerHPs.ContainsKey(targetedPlayer.playerSteamId) ? UpgradeBus.instance.playerHPs[targetedPlayer.playerSteamId] : 100);
			targetedPlayer.ResetPlayerBloodObjects(targetedPlayer.isPlayerDead);
			if (targetedPlayer.isPlayerDead || targetedPlayer.isPlayerControlled)
			{
				targetedPlayer.isClimbingLadder = false;
				targetedPlayer.ResetZAndXRotation();
				((Collider)targetedPlayer.thisController).enabled = true;
				targetedPlayer.health = num;
				targetedPlayer.disableLookInput = false;
				if (targetedPlayer.isPlayerDead)
				{
					targetedPlayer.isPlayerDead = false;
					targetedPlayer.isPlayerControlled = true;
					targetedPlayer.isInElevator = false;
					targetedPlayer.isInHangarShipRoom = false;
					targetedPlayer.isInsideFactory = true;
					targetedPlayer.wasInElevatorLastFrame = false;
					StartOfRound.Instance.SetPlayerObjectExtrapolate(false);
					targetedPlayer.setPositionOfDeadPlayer = false;
					((Behaviour)targetedPlayer.helmetLight).enabled = false;
					targetedPlayer.Crouch(false);
					targetedPlayer.criticallyInjured = false;
					if ((Object)(object)targetedPlayer.playerBodyAnimator != (Object)null)
					{
						targetedPlayer.playerBodyAnimator.SetBool("Limp", false);
					}
					targetedPlayer.bleedingHeavily = false;
					targetedPlayer.activatingItem = false;
					targetedPlayer.twoHanded = false;
					targetedPlayer.inSpecialInteractAnimation = false;
					targetedPlayer.disableSyncInAnimation = false;
					targetedPlayer.inAnimationWithEnemy = null;
					targetedPlayer.holdingWalkieTalkie = false;
					targetedPlayer.speakingToWalkieTalkie = false;
					targetedPlayer.isSinking = false;
					targetedPlayer.isUnderwater = false;
					targetedPlayer.sinkingValue = 0f;
					targetedPlayer.statusEffectAudio.Stop();
					targetedPlayer.DisableJetpackControlsLocally();
					targetedPlayer.health = num;
					targetedPlayer.mapRadarDotAnimator.SetBool("dead", false);
					targetedPlayer.deadBody = null;
					if ((Object)(object)targetedPlayer == (Object)(object)GameNetworkManager.Instance.localPlayerController)
					{
						HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false);
						targetedPlayer.hasBegunSpectating = false;
						HUDManager.Instance.RemoveSpectateUI();
						HUDManager.Instance.gameOverAnimator.SetTrigger("revive");
						targetedPlayer.hinderedMultiplier = 1f;
						targetedPlayer.isMovementHindered = 0;
						targetedPlayer.sourcesCausingSinking = 0;
						HUDManager.Instance.HideHUD(false);
					}
				}
				SoundManager.Instance.earsRingingTimer = 0f;
				targetedPlayer.voiceMuffledByEnemy = false;
				if ((Object)(object)targetedPlayer.currentVoiceChatIngameSettings == (Object)null)
				{
					StartOfRound.Instance.RefreshPlayerVoicePlaybackObjects();
				}
				if ((Object)(object)targetedPlayer.currentVoiceChatIngameSettings != (Object)null)
				{
					if ((Object)(object)targetedPlayer.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
					{
						targetedPlayer.currentVoiceChatIngameSettings.InitializeComponents();
					}
					if ((Object)(object)targetedPlayer.currentVoiceChatIngameSettings.voiceAudio == (Object)null)
					{
						return;
					}
					((Component)targetedPlayer.currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false;
				}
			}
			StartOfRound instance = StartOfRound.Instance;
			instance.livingPlayers++;
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)targetedPlayer)
			{
				targetedPlayer.bleedingHeavily = false;
				targetedPlayer.criticallyInjured = false;
				targetedPlayer.playerBodyAnimator.SetBool("Limp", false);
				targetedPlayer.health = num;
				HUDManager.Instance.UpdateHealthUI(num, false);
				targetedPlayer.spectatedPlayerScript = null;
				((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false;
				StartOfRound.Instance.SetSpectateCameraToGameOverMode(false, targetedPlayer);
				TimeOfDay.Instance.DisableAllWeather(false);
				StartOfRound.Instance.UpdatePlayerVoiceEffects();
				((Renderer)targetedPlayer.thisPlayerModel).enabled = true;
			}
			else
			{
				((Renderer)targetedPlayer.thisPlayerModel).enabled = true;
				((Renderer)targetedPlayer.thisPlayerModelLOD1).enabled = true;
				((Renderer)targetedPlayer.thisPlayerModelLOD2).enabled = true;
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_defibScript()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1556828106u, new RpcReceiveHandler(__rpc_handler_1556828106));
			NetworkManager.__rpc_func_table.Add(52528808u, new RpcReceiveHandler(__rpc_handler_52528808));
			NetworkManager.__rpc_func_table.Add(1174848284u, new RpcReceiveHandler(__rpc_handler_1174848284));
		}

		private static void __rpc_handler_1556828106(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((defibScript)(object)target).ReviveTargetedPlayerServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_52528808(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_003c: 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)
			//IL_0051: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 vector = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref vector);
				NetworkBehaviourReference netRef = default(NetworkBehaviourReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref netRef, default(ForNetworkSerializable));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((defibScript)(object)target).TelePlayerClientRpc(vector, netRef);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1174848284(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((defibScript)(object)target).ReviveTargetedPlayerClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "defibScript";
		}
	}
	internal class DivingKitScript : GrabbableObject
	{
		public override void Update()
		{
			if ((Object)(object)base.playerHeldBy != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				StartOfRound.Instance.drowningTimer = 1f;
			}
			((GrabbableObject)this).Update();
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "DivingKitScript";
		}
	}
	internal class exoskeletonScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Back Muscles";

		public static string PRICES_DEFAULT = "600,700,800";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.backLevel++;
			UpdatePlayerWeight();
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.exoskeleton = true;
			UpdatePlayerWeight();
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.exoskeleton = false;
			UpgradeBus.instance.backLevel = 0;
			UpdatePlayerWeight();
		}

		public override void Register()
		{
			base.Register();
		}

		public static float DecreasePossibleWeight(float defaultWeight)
		{
			if (!UpgradeBus.instance.exoskeleton)
			{
				return defaultWeight;
			}
			return defaultWeight * (UpgradeBus.instance.cfg.CARRY_WEIGHT_REDUCTION - (float)UpgradeBus.instance.backLevel * UpgradeBus.instance.cfg.CARRY_WEIGHT_INCREMENT);
		}

		public static void UpdatePlayerWeight()
		{
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (localPlayerController.ItemSlots.Length == 0)
			{
				return;
			}
			UpgradeBus.instance.alteredWeight = 1f;
			for (int i = 0; i < localPlayerController.ItemSlots.Length; i++)
			{
				GrabbableObject val = localPlayerController.ItemSlots[i];
				if (!((Object)(object)val == (Object)null))
				{
					UpgradeBus.instance.alteredWeight += Mathf.Clamp(DecreasePossibleWeight(val.itemProperties.weight - 1f), 0f, 10f);
				}
			}
			localPlayerController.carryWeight = UpgradeBus.instance.alteredWeight;
			if (localPlayerController.carryWeight < 1f)
			{
				localPlayerController.carryWeight = 1f;
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "exoskeletonScript";
		}
	}
	internal class hunterScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Hunter";

		private static string[] lvl1 = new string[2] { "Hoarding bug", "Centipede" };

		private static string[] lvl2 = new string[4] { "Bunker Spider", "Hoarding bug", "Centipede", "Baboon hawk" };

		private static string[] lvl3 = new string[7] { "Bunker Spider", "Hoarding bug", "Centipede", "Baboon hawk", "Flowerman", "Crawler", "MouthDog" };

		private static Dictionary<string, string> monsterNames = new Dictionary<string, string>
		{
			{ "Hoarding bug", "Hoarding Bug" },
			{ "Centipede", "Snare Flea" },
			{ "Bunker Spider", "Bunker Spider" },
			{ "Baboon hawk", "Baboon Hawk" },
			{ "Flowerman", "Bracken" },
			{ "Crawler", "Half/Thumper" },
			{ "MouthDog", "Eyeless Dog" }
		};

		public static Dictionary<int, string[]> tiers = new Dictionary<int, string[]>
		{
			{ 0, lvl1 },
			{ 1, lvl2 },
			{ 2, lvl3 }
		};

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.huntLevel++;
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.hunter = true;
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.hunter = false;
			UpgradeBus.instance.huntLevel = 0;
		}

		public override void Register()
		{
			base.Register();
		}

		public static string GetHunterInfo(int level, int price)
		{
			string text = ((level == 1) ? string.Join(", ", tiers[level - 1]) : string.Join(", ", tiers[level - 1].Except(tiers[level - 2]).ToArray()));
			string text2 = "";
			string[] array = text.Split(", ");
			foreach (string key in array)
			{
				text2 = text2 + monsterNames[key] + ", ";
			}
			text2 = text2.Substring(0, text2.Length - 2);
			text2 += "\n";
			return string.Format(AssetBundleHandler.GetInfoFromJSON(UPGRADE_NAME), level, price, text2);
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "hunterScript";
		}
	}
	internal class lightningRodScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Lightning Rod";

		public static lightningRodScript instance;

		private new static LGULogger logger;

		public static string ENABLED_SECTION = "Enable " + UPGRADE_NAME + " Upgrade";

		public static bool ENABLED_DEFAULT = true;

		public static string ENABLED_DESCRIPTION = "A device which redirects lightning bolts to the ship.";

		public static string PRICE_SECTION = UPGRADE_NAME + " Price";

		public static int PRICE_DEFAULT = 1000;

		public static string ACTIVE_SECTION = "Active on Purchase";

		public static bool ACTIVE_DEFAULT = true;

		public static string ACTIVE_DESCRIPTION = "If true: " + UPGRADE_NAME + " will be active on purchase.";

		private static string LOAD_COLOUR = "#FF0000";

		private static string LOAD_MESSAGE = "\n<color=" + LOAD_COLOUR + ">" + UPGRADE_NAME + " is active!</color>";

		private static string UNLOAD_COLOUR = LOAD_COLOUR;

		private static string UNLOAD_MESSAGE = "\n<color=" + UNLOAD_COLOUR + ">" + UPGRADE_NAME + " has been disabled</color>";

		public static string ACCESS_DENIED_MESSAGE = "You don't have access to this command yet. Purchase the '" + UPGRADE_NAME + "'.\n";

		public static string TOGGLE_ON_MESSAGE = UPGRADE_NAME + " has been enabled. Lightning bolts will now be redirected to the ship.\n";

		public static string TOGGLE_OFF_MESSAGE = UPGRADE_NAME + " has been disabled. Lightning bolts will no longer be redirected to the ship.\n";

		public static string DIST_SECTION = "Effective Distance of " + UPGRADE_NAME + ".";

		public static float DIST_DEFAULT = 175f;

		public static string DIST_DESCRIPTION = "The closer you are the more likely the rod will reroute lightning.";

		public bool CanTryInterceptLightning { get; internal set; }

		public bool LightningIntercepted { get; internal set; }

		private void Awake()
		{
			instance = this;
			logger = new LGULogger(UPGRADE_NAME);
		}

		private void Start()
		{
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			UpgradeBus.instance.UpgradeObjects.Add(UPGRADE_NAME, ((Component)this).gameObject);
		}

		public override void Increment()
		{
		}

		public override void load()
		{
			UpgradeBus.instance.lightningRod = true;
			UpgradeBus.instance.lightningRodActive = UpgradeBus.instance.cfg.LIGHTNING_ROD_ACTIVE;
			TextMeshProUGUI chatText = HUDManager.Instance.chatText;
			((TMP_Text)chatText).text = ((TMP_Text)chatText).text + LOAD_MESSAGE;
		}

		public override void Register()
		{
			if (!UpgradeBus.instance.UpgradeObjects.ContainsKey(UPGRADE_NAME))
			{
				UpgradeBus.instance.UpgradeObjects.Add(UPGRADE_NAME, ((Component)this).gameObject);
			}
		}

		public override void Unwind()
		{
			UpgradeBus.instance.lightningRod = false;
			UpgradeBus.instance.lightningRodActive = false;
			TextMeshProUGUI chatText = HUDManager.Instance.chatText;
			((TMP_Text)chatText).text = ((TMP_Text)chatText).text + UNLOAD_MESSAGE;
		}

		public static void TryInterceptLightning(ref StormyWeather __instance, ref GrabbableObject ___targetingMetalObject)
		{
			//IL_0037: 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)
			if (!instance.CanTryInterceptLightning)
			{
				return;
			}
			instance.CanTryInterceptLightning = false;
			Terminal terminal = UpgradeBus.instance.GetTerminal();
			float num = Vector3.Distance(((Component)___targetingMetalObject).transform.position, ((Component)terminal).transform.position);
			logger.LogInfo($"Distance from ship: {num}");
			logger.LogInfo($"Effective distance of the lightning rod: {UpgradeBus.instance.cfg.LIGHTNING_ROD_DIST}");
			if (!(num > UpgradeBus.instance.cfg.LIGHTNING_ROD_DIST))
			{
				num /= UpgradeBus.instance.cfg.LIGHTNING_ROD_DIST;
				float num2 = 1f - num;
				float value = Random.value;
				logger.LogInfo($"Number to beat: {num2}");
				logger.LogInfo($"Number: {value}");
				if (value < num2)
				{
					logger.LogInfo("Planning interception...");
					__instance.staticElectricityParticle.Stop();
					instance.LightningIntercepted = true;
					LGUStore.instance.CoordinateInterceptionClientRpc();
				}
			}
		}

		public static void RerouteLightningBolt(ref Vector3 strikePosition, ref StormyWeather __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			logger.LogInfo("Intercepted Lightning Strike...");
			Terminal terminal = UpgradeBus.instance.GetTerminal();
			strikePosition = ((Component)terminal).transform.position;
			instance.LightningIntercepted = false;
			((Component)__instance.staticElectricityParticle).gameObject.SetActive(true);
		}

		public static void ToggleLightningRod(ref TerminalNode __result)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			UpgradeBus.instance.lightningRodActive = !UpgradeBus.instance.lightningRodActive;
			TerminalNode val = new TerminalNode();
			val.displayText = (UpgradeBus.instance.lightningRodActive ? TOGGLE_ON_MESSAGE : TOGGLE_OFF_MESSAGE);
			val.clearPreviousText = true;
			__result = val;
		}

		public static void AccessDeniedMessage(ref TerminalNode __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			TerminalNode val = new TerminalNode();
			val.displayText = ACCESS_DENIED_MESSAGE;
			val.clearPreviousText = true;
			__result = val;
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "lightningRodScript";
		}
	}
	public class lockSmithScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Locksmith";

		private GameObject pin1;

		private GameObject pin2;

		private GameObject pin3;

		private GameObject pin4;

		private GameObject pin5;

		private List<GameObject> pins;

		private List<int> order = new List<int> { 0, 1, 2, 3, 4 };

		private int currentPin = 0;

		public DoorLock currentDoor = null;

		private bool canPick = false;

		public int timesStruck;

		private void Start()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
			Transform child = ((Component)this).transform.GetChild(0).GetChild(0).GetChild(0);
			pin1 = ((Component)child.GetChild(0)).gameObject;
			pin2 = ((Component)child.GetChild(1)).gameObject;
			pin3 = ((Component)child.GetChild(2)).gameObject;
			pin4 = ((Component)child.GetChild(3)).gameObject;
			pin5 = ((Component)child.GetChild(4)).gameObject;
			((UnityEvent)((Component)pin1.transform.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				StrikePin(0);
			});
			((UnityEvent)((Component)pin2.transform.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				StrikePin(1);
			});
			((UnityEvent)((Component)pin3.transform.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				StrikePin(2);
			});
			((UnityEvent)((Component)pin4.transform.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				StrikePin(3);
			});
			((UnityEvent)((Component)pin5.transform.GetChild(0)).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				StrikePin(4);
			});
			pins = new List<GameObject> { pin1, pin2, pin3, pin4, pin5 };
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.lockSmith = true;
			UpgradeBus.instance.lockScript = this;
		}

		public override void Register()
		{
			base.Register();
		}

		private void Update()
		{
			if (((ButtonControl)Keyboard.current[(Key)60]).wasPressedThisFrame && ((Component)((Component)this).transform.GetChild(0)).gameObject.activeInHierarchy)
			{
				((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(false);
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
			}
		}

		public void BeginLockPick()
		{
			//IL_006c: 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)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(true);
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
			canPick = false;
			currentPin = 0;
			for (int i = 0; i < pins.Count; i++)
			{
				float num = Random.Range(40f, 90f);
				pins[i].transform.localPosition = new Vector3(pins[i].transform.localPosition.x, num, pins[i].transform.localPosition.z);
			}
			RandomizeListOrder(order);
			((MonoBehaviour)this).StartCoroutine(CommunicateOrder(order));
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.lockSmith = false;
		}

		public void StrikePin(int i)
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			if (!canPick)
			{
				return;
			}
			timesStruck++;
			if (i == order[currentPin])
			{
				currentPin++;
				pins[i].transform.localPosition = new Vector3(pins[i].transform.localPosition.x, 35f, pins[i].transform.localPosition.z);
				if (currentPin == 5)
				{
					Cursor.visible = false;
					Cursor.lockState = (CursorLockMode)1;
					((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(false);
					currentDoor.UnlockDoorSyncWithServer();
				}
				RoundManager.Instance.PlayAudibleNoise(((Component)currentDoor).transform.position, 10f, 0.65f, timesStruck, false, 0);
			}
			else
			{
				BeginLockPick();
				RoundManager.Instance.PlayAudibleNoise(((Component)currentDoor).transform.position, 30f, 0.65f, timesStruck, false, 0);
			}
		}

		private void RandomizeListOrder<T>(List<T> list)
		{
			int num = list.Count;
			Random random = new Random();
			while (num > 1)
			{
				num--;
				int index = random.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}

		private IEnumerator CommunicateOrder(List<int> lst)
		{
			yield return (object)new WaitForSeconds(0.75f);
			for (int i = 0; i < lst.Count; i++)
			{
				((Graphic)pins[lst[i]].GetComponent<Image>()).color = Color.green;
				yield return (object)new WaitForSeconds(0.25f);
				((Graphic)pins[lst[i]].GetComponent<Image>()).color = Color.white;
			}
			canPick = true;
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "lockSmithScript";
		}
	}
	internal class MedkitScript : GrabbableObject
	{
		public AudioClip error;

		public AudioClip use;

		private AudioSource audio;

		private int uses = 0;

		public override void Start()
		{
			audio = ((Component)this).GetComponent<AudioSource>();
			((GrabbableObject)this).Start();
		}

		public override void DiscardItem()
		{
			base.playerHeldBy.activatingItem = false;
			((GrabbableObject)this).DiscardItem();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (base.itemUsedUp)
			{
				HUDManager.Instance.DisplayTip("NO MORE USES!", "This medkit doesn't have anymore supplies!", true, false, "LC_Tip1");
			}
			else
			{
				if (!Mouse.current.leftButton.isPressed)
				{
					return;
				}
				int num = (UpgradeBus.instance.playerHPs.ContainsKey(base.playerHeldBy.playerSteamId) ? UpgradeBus.instance.playerHPs[base.playerHeldBy.playerSteamId] : 100);
				if (base.playerHeldBy.health >= num)
				{
					audio.PlayOneShot(error);
					Debug.Log((object)"LGU: Can't use medkit - full health");
					return;
				}
				audio.PlayOneShot(use);
				uses++;
				int num2 = UpgradeBus.instance.cfg.MEDKIT_HEAL_VALUE;
				int num3 = base.playerHeldBy.health + num2;
				if (num3 > num)
				{
					num2 -= num3 - num;
				}
				base.playerHeldBy.DamagePlayer(-num2, false, true, (CauseOfDeath)0, 0, false, Vector3.zero);
				if (uses >= UpgradeBus.instance.cfg.MEDKIT_USES)
				{
					base.itemUsedUp = true;
					HUDManager.Instance.DisplayTip("NO MORE USES!", "This medkit doesn't have anymore supplies!", true, false, "LC_Tip1");
				}
				if (base.playerHeldBy.health >= 20)
				{
					base.playerHeldBy.MakeCriticallyInjured(false);
				}
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "MedkitScript";
		}
	}
	internal class NightVisionItemScript : GrabbableObject
	{
		public override void DiscardItem()
		{
			base.playerHeldBy.activatingItem = false;
			((GrabbableObject)this).DiscardItem();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!Mouse.current.leftButton.isPressed)
			{
				return;
			}
			if (UpgradeBus.instance.nightVision)
			{
				TextMeshProUGUI chatText = HUDManager.Instance.chatText;
				((TMP_Text)chatText).text = ((TMP_Text)chatText).text + "<color=#FF0000>Night vision is already active!</color>";
				return;
			}
			if (!UpgradeBus.instance.IndividualUpgrades[nightVisionScript.UPGRADE_NAME])
			{
				LGUStore.instance.EnableNightVisionServerRpc();
			}
			else
			{
				UpgradeBus.instance.UpgradeObjects[nightVisionScript.UPGRADE_NAME].GetComponent<nightVisionScript>().EnableOnClient();
			}
			base.playerHeldBy.DespawnHeldObject();
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "NightVisionItemScript";
		}
	}
	internal class nightVisionScript : BaseUpgrade
	{
		private float nightBattery;

		private float regen;

		private float drain;

		private Transform batteryBar;

		private PlayerControllerB client;

		private bool batteryExhaustion;

		private Key toggleKey;

		public static string UPGRADE_NAME = "NV Headset Batteries";

		public static string PRICES_DEFAULT = "300,400,500";

		private void Start()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
			batteryBar = ((Component)((Component)this).transform.GetChild(0).GetChild(0)).transform;
			((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(false);
			if (Enum.TryParse<Key>(UpgradeBus.instance.cfg.TOGGLE_NIGHT_VISION_KEY, out Key result))
			{
				toggleKey = result;
			}
			else
			{
				toggleKey = (Key)53;
			}
			regen = UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_SPEED;
			drain = UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_SPEED;
		}

		public override void Register()
		{
			base.Register();
		}

		private void LateUpdate()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)client == (Object)null)
			{
				return;
			}
			if (((ButtonControl)Keyboard.current[toggleKey]).wasPressedThisFrame && !batteryExhaustion)
			{
				Toggle();
			}
			float num = UpgradeBus.instance.cfg.NIGHT_BATTERY_MAX + (float)UpgradeBus.instance.nightVisionLevel * UpgradeBus.instance.cfg.NIGHT_VIS_BATTERY_INCREMENT;
			if (UpgradeBus.instance.nightVisionActive)
			{
				nightBattery -= Time.deltaTime * (UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_SPEED - (float)UpgradeBus.instance.nightVisionLevel * UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_INCREMENT);
				nightBattery = Mathf.Clamp(nightBattery, 0f, num);
				((Component)batteryBar.parent).gameObject.SetActive(true);
				if (nightBattery <= 0f)
				{
					TurnOff(exhaust: true);
				}
			}
			else if (!batteryExhaustion)
			{
				nightBattery += Time.deltaTime * (UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_SPEED + (float)UpgradeBus.instance.nightVisionLevel * UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_INCREMENT);
				nightBattery = Mathf.Clamp(nightBattery, 0f, num);
				if (nightBattery >= num)
				{
					((Component)batteryBar.parent).gameObject.SetActive(false);
				}
				else
				{
					((Component)batteryBar.parent).gameObject.SetActive(true);
				}
			}
			if (client.isInsideFactory || UpgradeBus.instance.nightVisionActive)
			{
				((Behaviour)client.nightVision).enabled = true;
			}
			else
			{
				((Behaviour)client.nightVision).enabled = false;
			}
			float num2 = nightBattery / num;
			batteryBar.localScale = new Vector3(num2, 1f, 1f);
		}

		private void Toggle()
		{
			UpgradeBus.instance.nightVisionActive = !UpgradeBus.instance.nightVisionActive;
			if (UpgradeBus.instance.nightVisionActive)
			{
				TurnOn();
			}
			else
			{
				TurnOff();
			}
			regen = UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_SPEED;
			drain = UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_SPEED;
		}

		private void TurnOff(bool exhaust = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			UpgradeBus.instance.nightVisionActive = false;
			client.nightVision.color = UpgradeBus.instance.nightVisColor;
			client.nightVision.range = UpgradeBus.instance.nightVisRange;
			client.nightVision.intensity = UpgradeBus.instance.nightVisIntensity;
			if (exhaust)
			{
				batteryExhaustion = true;
				((MonoBehaviour)this).StartCoroutine(BatteryRecovery());
			}
		}

		private void TurnOn()
		{
			//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_0064: Unknown result type (might be due to invalid IL or missing references)
			UpgradeBus.instance.nightVisColor = client.nightVision.color;
			UpgradeBus.instance.nightVisRange = client.nightVision.range;
			UpgradeBus.instance.nightVisIntensity = client.nightVision.intensity;
			client.nightVision.color = UpgradeBus.instance.cfg.NIGHT_VIS_COLOR;
			client.nightVision.range = UpgradeBus.instance.cfg.NIGHT_VIS_RANGE + (float)UpgradeBus.instance.nightVisionLevel * UpgradeBus.instance.cfg.NIGHT_VIS_RANGE_INCREMENT;
			client.nightVision.intensity = UpgradeBus.instance.cfg.NIGHT_VIS_INTENSITY + (float)UpgradeBus.instance.nightVisionLevel * UpgradeBus.instance.cfg.NIGHT_VIS_INTENSITY_INCREMENT;
			nightBattery -= UpgradeBus.instance.cfg.NIGHT_VIS_STARTUP;
		}

		private IEnumerator BatteryRecovery()
		{
			yield return (object)new WaitForSeconds(UpgradeBus.instance.cfg.NIGHT_VIS_EXHAUST);
			batteryExhaustion = false;
		}

		public override void Increment()
		{
			UpgradeBus.instance.nightVisionLevel++;
			LGUStore.instance.UpdateLGUSaveServerRpc(GameNetworkManager.Instance.localPlayerController.playerSteamId, JsonConvert.SerializeObject((object)new SaveInfo()));
		}

		public override void load()
		{
			EnableOnClient(save: false);
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.nightVision = false;
			UpgradeBus.instance.nightVisionLevel = 0;
			DisableOnClient();
		}

		public void EnableOnClient(bool save = true)
		{
			if ((Object)(object)client == (Object)null)
			{
				client = GameNetworkManager.Instance.localPlayerController;
			}
			((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(true);
			UpgradeBus.instance.nightVision = true;
			if (save)
			{
				LGUStore.instance.UpdateLGUSaveServerRpc(client.playerSteamId, JsonConvert.SerializeObject((object)new SaveInfo()));
			}
			TextMeshProUGUI chatText = HUDManager.Instance.chatText;
			((TMP_Text)chatText).text = ((TMP_Text)chatText).text + "\n<color=#FF0000>Press " + UpgradeBus.instance.cfg.TOGGLE_NIGHT_VISION_KEY + " to toggle Night Vision!!!</color>";
		}

		public void DisableOnClient()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			UpgradeBus.instance.nightVisionActive = false;
			client.nightVision.color = UpgradeBus.instance.nightVisColor;
			client.nightVision.range = UpgradeBus.instance.nightVisRange;
			client.nightVision.intensity = UpgradeBus.instance.nightVisIntensity;
			((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(false);
			UpgradeBus.instance.nightVision = false;
			LGUStore.instance.UpdateLGUSaveServerRpc(client.playerSteamId, JsonConvert.SerializeObject((object)new SaveInfo()));
			client = null;
		}

		public static string GetNightVisionInfo(int level, int price)
		{
			if (level == 1)
			{
				float num = (UpgradeBus.instance.cfg.NIGHT_BATTERY_MAX - UpgradeBus.instance.cfg.NIGHT_BATTERY_MAX * UpgradeBus.instance.cfg.NIGHT_VIS_STARTUP) / UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_SPEED;
				float num2 = UpgradeBus.instance.cfg.NIGHT_BATTERY_MAX / UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_SPEED;
				return string.Format(AssetBundleHandler.GetInfoFromJSON(UPGRADE_NAME), level, price, num, num2);
			}
			float num3 = Mathf.Clamp(UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_SPEED + UpgradeBus.instance.cfg.NIGHT_VIS_REGEN_INCREMENT * (float)(level - 1), 0f, 1000f);
			float num4 = Mathf.Clamp(UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_SPEED - UpgradeBus.instance.cfg.NIGHT_VIS_DRAIN_INCREMENT * (float)(level - 1), 0f, 1000f);
			float num5 = UpgradeBus.instance.cfg.NIGHT_BATTERY_MAX + UpgradeBus.instance.cfg.NIGHT_VIS_BATTERY_INCREMENT * (float)(level - 1);
			string text = "infinite";
			if (num4 != 0f)
			{
				text = ((num5 - num5 * UpgradeBus.instance.cfg.NIGHT_VIS_STARTUP) / num4).ToString("F2");
			}
			string text2 = "infinite";
			if (num3 != 0f)
			{
				text2 = (num5 / num3).ToString("F2");
			}
			return string.Format(AssetBundleHandler.GetInfoFromJSON(UPGRADE_NAME), level, price, text, text2);
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "nightVisionScript";
		}
	}
	public class pagerScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Fast Encryption";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.pager = true;
			UpgradeBus.instance.pageScript = this;
		}

		public override void Register()
		{
			base.Register();
		}

		[ServerRpc(RequireOwnership = false)]
		public void ReqBroadcastChatServerRpc(string msg)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(797180313u, val, (RpcDelivery)0);
				bool flag = msg != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(msg, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 797180313u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ReceiveChatClientRpc(msg);
			}
		}

		[ClientRpc]
		public void ReceiveChatClientRpc(string msg)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(58640511u, val, (RpcDelivery)0);
				bool flag = msg != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(msg, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 58640511u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				SignalTranslator val3 = Object.FindObjectOfType<SignalTranslator>();
				if ((Object)(object)val3 != (Object)null)
				{
					HUDManager.Instance.UIAudio.PlayOneShot(val3.startTransmissionSFX);
				}
				TextMeshProUGUI chatText = HUDManager.Instance.chatText;
				((TMP_Text)chatText).text = ((TMP_Text)chatText).text + "\n<color=#FF0000>Terminal</color><color=#0000FF>:</color> <color=#FF00FF>" + msg + "</color>";
				HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, 4f, 1f, 0.2f);
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_pagerScript()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(797180313u, new RpcReceiveHandler(__rpc_handler_797180313));
			NetworkManager.__rpc_func_table.Add(58640511u, new RpcReceiveHandler(__rpc_handler_58640511));
		}

		private static void __rpc_handler_797180313(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string msg = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref msg, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((pagerScript)(object)target).ReqBroadcastChatServerRpc(msg);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_58640511(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string msg = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref msg, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((pagerScript)(object)target).ReceiveChatClientRpc(msg);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "pagerScript";
		}
	}
	internal class playerHealthScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Stimpack";

		private static int DEFAULT_HEALTH = 100;

		public static string ENABLED_SECTION = "Enable " + UPGRADE_NAME + " Upgrade";

		public static bool ENABLED_DEFAULT = true;

		public static string ENABLED_DESCRIPTION = "Increases player's health.";

		public static string PRICE_SECTION = UPGRADE_NAME + " Price";

		public static int PRICE_DEFAULT = 600;

		public static string PRICES_DEFAULT = "300, 450, 600";

		public static string ADDITIONAL_HEALTH_UNLOCK_SECTION = "Initial health boost";

		public static int ADDITIONAL_HEALTH_UNLOCK_DEFAULT = 20;

		public static string ADDITIONAL_HEALTH_UNLOCK_DESCRIPTION = "Amount of health gained when unlocking the upgrade";

		public static string ADDITIONAL_HEALTH_INCREMENT_SECTION = "Additional health boost";

		public static int ADDITIONAL_HEALTH_INCREMENT_DEFAULT = 20;

		public static string ADDITIONAL_HEALTH_INCREMENT_DESCRIPTION = "Every time " + UPGRADE_NAME + " is upgraded this value will be added to the value above.";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			UpgradeBus.instance.UpgradeObjects.Add(UPGRADE_NAME, ((Component)this).gameObject);
		}

		public override void Increment()
		{
			UpgradeBus.instance.playerHealthLevel++;
			LGUStore.instance.UpdatePlayerNewHealthsServerRpc(GameNetworkManager.Instance.localPlayerController.playerSteamId, DEFAULT_HEALTH + UpgradeBus.instance.cfg.PLAYER_HEALTH_ADDITIONAL_HEALTH_UNLOCK + UpgradeBus.instance.playerHealthLevel * UpgradeBus.instance.cfg.PLAYER_HEALTH_ADDITIONAL_HEALTH_INCREMENT);
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.playerHealth = true;
			LGUStore.instance.UpdatePlayerNewHealthsServerRpc(GameNetworkManager.Instance.localPlayerController.playerSteamId, DEFAULT_HEALTH + UpgradeBus.instance.cfg.PLAYER_HEALTH_ADDITIONAL_HEALTH_UNLOCK + UpgradeBus.instance.playerHealthLevel * UpgradeBus.instance.cfg.PLAYER_HEALTH_ADDITIONAL_HEALTH_INCREMENT);
		}

		public override void Register()
		{
			base.Register();
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.playerHealthLevel = 0;
			UpgradeBus.instance.playerHealth = false;
			LGUStore.instance.UpdatePlayerNewHealthsServerRpc(GameNetworkManager.Instance.localPlayerController.playerSteamId, DEFAULT_HEALTH);
		}

		public static void CheckAdditionalHealth(StartOfRound __instance)
		{
			PlayerControllerB[] allPlayerScripts = __instance.allPlayerScripts;
			PlayerControllerB[] array = allPlayerScripts;
			foreach (PlayerControllerB player in array)
			{
				UpdateMaxHealth(player);
			}
		}

		public static int CheckForAdditionalHealth()
		{
			if (UpgradeBus.instance.playerHPs.ContainsKey(GameNetworkManager.Instance.localPlayerController.playerSteamId))
			{
				return UpgradeBus.instance.playerHPs[GameNetworkManager.Instance.localPlayerController.playerSteamId];
			}
			return DEFAULT_HEALTH;
		}

		public static void UpdateMaxHealth(PlayerControllerB player)
		{
			if (UpgradeBus.instance.playerHPs.ContainsKey(player.playerSteamId))
			{
				player.health = UpgradeBus.instance.playerHPs[player.playerSteamId];
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "playerHealthScript";
		}
	}
	internal class proteinPowderScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Protein Powder";

		private static int CRIT_DAMAGE_VALUE = 100;

		public static string ENABLED_SECTION = "Enable " + UPGRADE_NAME + " Upgrade";

		public static bool ENABLED_DEFAULT = true;

		public static string ENABLED_DESCRIPTION = "Do more damage with shovels";

		public static string PRICE_SECTION = "Price of " + UPGRADE_NAME + " Upgrade";

		public static int PRICE_DEFAULT = 1000;

		public static string UNLOCK_FORCE_SECTION = "Initial additional hit force";

		public static int UNLOCK_FORCE_DEFAULT = 1;

		public static string UNLOCK_FORCE_DESCRIPTION = "The value added to hit force on initial unlock.";

		public static string INCREMENT_FORCE_SECTION = "Additional hit force per level";

		public static int INCREMENT_FORCE_DEFAULT = 1;

		public static string INCREMENT_FORCE_DESCRIPTION = "Every time " + UPGRADE_NAME + " is upgraded this value will be added to the value above.";

		public static string PRICES_DEFAULT = "700";

		public static string CRIT_CHANCE_SECTION = "Chance of dealing a crit which will instakill the enemy.";

		public static float CRIT_CHANCE_DEFAULT = 0.01f;

		public static string CRIT_CHANCE_DESCRIPTION = "This value is only valid when maxed out " + UPGRADE_NAME + ". Any previous levels will not apply crit.";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.proteinLevel++;
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.proteinPowder = true;
		}

		public override void Register()
		{
			base.Register();
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.proteinLevel = 0;
			UpgradeBus.instance.proteinPowder = false;
		}

		public static int GetShovelHitForce(int force)
		{
			return (!UpgradeBus.instance.proteinPowder) ? force : (TryToCritEnemy() ? CRIT_DAMAGE_VALUE : (UpgradeBus.instance.cfg.PROTEIN_INCREMENT * UpgradeBus.instance.proteinLevel + UpgradeBus.instance.cfg.PROTEIN_UNLOCK_FORCE + force));
		}

		private static bool TryToCritEnemy()
		{
			int num = UpgradeBus.instance.cfg.PROTEIN_UPGRADE_PRICES.Split(',').Length;
			int proteinLevel = UpgradeBus.instance.proteinLevel;
			if (proteinLevel != num)
			{
				return false;
			}
			return Random.value < UpgradeBus.instance.cfg.PROTEIN_CRIT_CHANCE;
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "proteinPowderScript";
		}
	}
	internal class runningShoeScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Running Shoes";

		public static string PRICES_DEFAULT = "500,750,1000";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			localPlayerController.movementSpeed += UpgradeBus.instance.cfg.MOVEMENT_INCREMENT;
			UpgradeBus.instance.runningLevel++;
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.runningShoes = false;
			UpgradeBus.instance.runningLevel = 0;
			GameNetworkManager.Instance.localPlayerController.movementSpeed = 4.6f;
		}

		public override void Register()
		{
			base.Register();
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.runningShoes = true;
			GameNetworkManager.Instance.localPlayerController.movementSpeed = UpgradeBus.instance.cfg.MOVEMENT_SPEED;
			float num = 0f;
			for (int i = 0; i < UpgradeBus.instance.runningLevel; i++)
			{
				num += UpgradeBus.instance.cfg.MOVEMENT_INCREMENT;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			localPlayerController.movementSpeed += num;
		}

		public static float ApplyPossibleReducedNoiseRange(float defaultValue)
		{
			if (!UpgradeBus.instance.runningShoes || UpgradeBus.instance.runningLevel != UpgradeBus.instance.cfg.RUNNING_SHOES_UPGRADE_PRICES.Split(',').Length)
			{
				return defaultValue;
			}
			return Mathf.Clamp(defaultValue - UpgradeBus.instance.cfg.NOISE_REDUCTION, 0f, defaultValue);
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "runningShoeScript";
		}
	}
	internal class SampleItem : PhysicsProp
	{
		public override void EquipItem()
		{
			ParticleSystem componentInChildren = ((Component)this).GetComponentInChildren<ParticleSystem>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.Play();
			}
			((GrabbableObject)this).EquipItem();
		}

		public override void DiscardItem()
		{
			ParticleSystem componentInChildren = ((Component)this).GetComponentInChildren<ParticleSystem>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.Play();
			}
			((GrabbableObject)this).DiscardItem();
		}

		public override void PocketItem()
		{
			ParticleSystem componentInChildren = ((Component)this).GetComponentInChildren<ParticleSystem>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.Stop();
				componentInChildren.Clear();
			}
			((GrabbableObject)this).PocketItem();
		}

		protected override void __initializeVariables()
		{
			((PhysicsProp)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "SampleItem";
		}
	}
	internal class strongerScannerScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Better Scanner";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.scanLevel++;
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.scannerUpgrade = true;
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.scannerUpgrade = false;
			UpgradeBus.instance.scanLevel = 0;
		}

		public override void Register()
		{
			base.Register();
		}

		public static void AddScannerNodeToValve(ref SteamValveHazard steamValveHazard)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (UpgradeBus.instance.scannerUpgrade)
			{
				GameObject val = Object.Instantiate<GameObject>(GameObject.Find("ScanNode"), ((Component)steamValveHazard).transform.position, Quaternion.Euler(Vector3.zero), ((Component)steamValveHazard).transform);
				ScanNodeProperties component = val.GetComponent<ScanNodeProperties>();
				component.headerText = "Bursted Steam Valve";
				component.subText = "Fix it to get rid of the steam";
				component.nodeType = 0;
				component.creatureScanID = -1;
			}
		}

		public static void RemoveScannerNodeFromValve(ref SteamValveHazard steamValveHazard)
		{
			Object.Destroy((Object)(object)((Component)steamValveHazard).gameObject.GetComponentInChildren<ScanNodeProperties>());
		}

		public static string GetBetterScannerInfo(int level, int price)
		{
			switch (level)
			{
			case 1:
				return string.Format(AssetBundleHandler.GetInfoFromJSON("Better Scanner1"), level, price, UpgradeBus.instance.cfg.NODE_DISTANCE_INCREASE, UpgradeBus.instance.cfg.SHIP_AND_ENTRANCE_DISTANCE_INCREASE);
			case 2:
				return string.Format(AssetBundleHandler.GetInfoFromJSON("Better Scanner2"), level, price);
			case 3:
			{
				string text = string.Format(AssetBundleHandler.GetInfoFromJSON("Better Scanner3"), level, price, UpgradeBus.instance.cfg.BETTER_SCANNER_ENEMIES ? " and enemies" : "");
				return text + "hives and scrap command display the location of the most valuable hives and scrap on the map.\n";
			}
			default:
				return "";
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "strongerScannerScript";
		}
	}
	internal class strongLegsScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Strong Legs";

		public static string PRICES_DEFAULT = "150,190,250";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.legLevel++;
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.strongLegs = false;
			UpgradeBus.instance.legLevel = 0;
			GameNetworkManager.Instance.localPlayerController.jumpForce = 13f;
		}

		public override void Register()
		{
			base.Register();
		}

		public override void load()
		{
			base.load();
			UpgradeBus.instance.strongLegs = true;
			GameNetworkManager.Instance.localPlayerController.jumpForce = UpgradeBus.instance.cfg.JUMP_FORCE;
			float num = 0f;
			for (int i = 0; i < UpgradeBus.instance.legLevel; i++)
			{
				num += UpgradeBus.instance.cfg.JUMP_FORCE_INCREMENT;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			localPlayerController.jumpForce += num;
		}

		public static int ReduceFallDamage(int defaultValue)
		{
			if (!UpgradeBus.instance.strongLegs || UpgradeBus.instance.legLevel != UpgradeBus.instance.cfg.STRONG_LEGS_UPGRADE_PRICES.Split(',').Length)
			{
				return defaultValue;
			}
			return (int)((float)defaultValue * (1f - UpgradeBus.instance.cfg.STRONG_LEGS_REDUCE_FALL_DAMAGE_MULTIPLIER));
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "strongLegsScript";
		}
	}
	public class terminalFlashScript : BaseUpgrade
	{
		public static string UPGRADE_NAME = "Discombobulator";

		public static string PRICES_DEFAULT = "330,460,620";

		private void Start()
		{
			upgradeName = UPGRADE_NAME;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Register();
		}

		private void Update()
		{
			if (UpgradeBus.instance.flashCooldown > 0f)
			{
				UpgradeBus.instance.flashCooldown -= Time.deltaTime;
			}
		}

		public override void load()
		{
			UpgradeBus.instance.terminalFlash = true;
			UpgradeBus.instance.flashScript = this;
			TextMeshProUGUI chatText = HUDManager.Instance.chatText;
			((TMP_Text)chatText).text = ((TMP_Text)chatText).text + "\n<color=#FF0000>Discombobulator is active!\nType 'cooldown' into the terminal for info!!!</color>";
		}

		public override void Register()
		{
			base.Register();
		}

		public override void Increment()
		{
			UpgradeBus.instance.discoLevel++;
		}

		public override void Unwind()
		{
			base.Unwind();
			UpgradeBus.instance.terminalFlash = false;
			UpgradeBus.instance.discoLevel = 0;
		}

		[ServerRpc(RequireOwnership = false)]
		public void PlayAudioAndUpdateCooldownServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1135781697u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1135781697u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					PlayAudioAndUpdateCooldownClientRpc();
				}
			}
		}

		[ClientRpc]
		private void PlayAudioAndUpdateCooldownClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1412806528u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1412806528u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			Terminal component = GameObject.Find("TerminalScript").GetComponent<Terminal>();
			component.terminalAudio.maxDistance = 100f;
			component.terminalAudio.PlayOneShot(UpgradeBus.instance.flashNoise);
			((MonoBehaviour)this).StartCoroutine(ResetRange(component));
			UpgradeBus.instance.flashCooldown = UpgradeBus.instance.cfg.DISCOMBOBULATOR_COOLDOWN;
			Collider[] array = Physics.OverlapSphere(((Component)component).transform.position, UpgradeBus.instance.cfg.DISCOMBOBULATOR_RADIUS, 524288);
			if (array.Length == 0)
			{
				return;
			}
			for (int i = 0; i < array.Length; i++)
			{
				EnemyAICollisionDetect component2 = ((Component)array[i]).GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component2 != (Object)null)
				{
					EnemyAI mainScript = component2.mainScript;
					if (CanDealDamage())
					{
						int num = UpgradeBus.instance.cfg.DISCOMBOBULATOR_INITIAL_DAMAGE + UpgradeBus.instance.cfg.DISCOMBOBULATOR_DAMAGE_INCREASE * (UpgradeBus.instance.discoLevel - UpgradeBus.instance.cfg.DISCOMBOBULATOR_DAMAGE_LEVEL);
						mainScript.HitEnemy(num, (PlayerControllerB)null, false);
					}
					if (!mainScript.isEnemyDead)
					{
						mainScript.SetEnemyStunned(true, UpgradeBus.instance.cfg.DISCOMBOBULATOR_STUN_DURATION + UpgradeBus.instance.cfg.DISCOMBOBULATOR_INCREMENT * (float)UpgradeBus.instance.discoLevel, (PlayerControllerB)null);
					}
				}
			}
		}

		private bool CanDealDamage()
		{
			return UpgradeBus.instance.cfg.DISCOMBOBULATOR_DAMAGE_LEVEL > 0 && UpgradeBus.instance.discoLevel + 1 >= UpgradeBus.instance.cfg.DISCOMBOBULATOR_DAMAGE_LEVEL;
		}

		private IEnumerator ResetRange(Terminal terminal)
		{
			yield return (object)new WaitForSeconds(2f);
			terminal.terminalAudio.maxDistance = 17f;
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_terminalFlashScript()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1135781697u, new RpcReceiveHandler(__rpc_handler_1135781697));
			NetworkManager.__rpc_func_table.Add(1412806528u, new RpcReceiveHandler(__rpc_handler_1412806528));
		}

		private static void __rpc_handler_1135781697(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((terminalFlashScript)(object)target).PlayAudioAndUpdateCooldownServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1412806528(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((terminalFlashScript)(object)target).PlayAudioAndUpdateCooldownClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "terminalFlashScript";
		}
	}
	internal class TPButtonScript : GrabbableObject
	{
		public AudioClip ItemBreak;

		public AudioClip error;

		public AudioClip buttonPress;

		private AudioSource audio;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			audio = ((Component)this).GetComponent<AudioSource>();
		}

		public override void DiscardItem()
		{
			base.playerHeldBy.activatingItem = false;
			((GrabbableObject)this).DiscardItem();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!Mouse.current.leftButton.isPressed)
			{
				return;
			}
			audio.PlayOneShot(buttonPress);
			if (!base.itemUsedUp)
			{
				ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>();
				ShipTeleporter val = null;
				ShipTeleporter[] array2 = array;
				foreach (ShipTeleporter val2 in array2)
				{
					if (!val2.isInverseTeleporter)
					{
						val = val2;
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					audio.PlayOneShot(error);
					return;
				}
				int num = -1;
				for (int j = 0; j < StartOfRound.Instance.mapScreen.radarTargets.Count(); j++)
				{
					if ((Object)(object)((Component)StartOfRound.Instance.mapScreen.radarTargets[j].transform).gameObject.GetComponent<PlayerControllerB>() == (Object)(object)base.playerHeldBy)
					{
						num = j;
					}
				}
				if (num == -1)
				{
					StartOfRound.Instance.mapScreen.targetedPlayer = base.playerHeldBy;
					UpgradeBus.instance.TPButtonPressed = true;
					val.PressTeleportButtonOnLocalClient();
					if (Random.Range(0f, 1f) > UpgradeBus.instance.cfg.CHANCE_TO_BREAK)
					{
						audio.PlayOneShot(ItemBreak);
						base.itemUsedUp = true;
						base.playerHeldBy.DespawnHeldObject();
					}
				}
				else
				{
					StartOfRound.Instance.mapScreen.SwitchRadarTargetAndSync(num);
					((MonoBehaviour)this).StartCoroutine(WaitToTP(val));
				}
			}
			else
			{
				audio.PlayOneShot(error);
			}
		}

		private IEnumerator WaitToTP(ShipTeleporter tele)
		{
			yield ret

BepInEx/plugins/ReservedFlashlightSlot.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using ReservedFlashlightSlot.Patches;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedFlashlightSlot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedFlashlightSlot")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5b7d6563-4e51-4a69-bcf9-fa1dea6eff75")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedFlashlightSlot
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> activateFlashlightKey;

		public static ConfigEntry<bool> hideFlashlightMeshShoulder;

		public static string activateFlashlightDisplayName;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			activateFlashlightKey = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedFlashlightSlot", "ActivateFlashlightKey", "<Keyboard>/f", "Activate flashlight keybind.");
			hideFlashlightMeshShoulder = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedFlashlightSlot", "HideFlashlightOnShoulder", false, "Hides the flashlight mesh while on your shoulder. Only applies in scenarios where you can view your player in third person.");
			activateFlashlightDisplayName = GetDisplayName(activateFlashlightKey.Value);
			currentConfigEntries.Add(((ConfigEntryBase)activateFlashlightKey).Definition.Key, (ConfigEntryBase)(object)activateFlashlightKey);
			currentConfigEntries.Add(((ConfigEntryBase)hideFlashlightMeshShoulder).Definition.Key, (ConfigEntryBase)(object)hideFlashlightMeshShoulder);
			TryRemoveOldConfigSettings();
		}

		public static string GetDisplayName(string key)
		{
			key = key.Replace("<Keyboard>/", "");
			key = key.Replace("<Mouse>/", "");
			string text = key;
			text = text.Replace("leftAlt", "Alt");
			text = text.Replace("rightAlt", "Alt");
			text = text.Replace("leftCtrl", "Ctrl");
			text = text.Replace("rightCtrl", "Ctrl");
			text = text.Replace("leftShift", "Shift");
			text = text.Replace("rightShift", "Shift");
			text = text.Replace("leftButton", "LMB");
			text = text.Replace("rightButton", "RMB");
			return text.Replace("middleButton", "MMB");
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static PlayerControllerB localPlayerController;

		private static InputAction activateFlashlightAction;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void InitActions()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			activateFlashlightAction = new InputAction((string)null, (InputActionType)0, ConfigSettings.activateFlashlightKey.Value, "Press", (string)null, (string)null);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void OnLocalPlayerConnect(PlayerControllerB __instance)
		{
			localPlayerController = __instance;
			if (((Component)localPlayerController).gameObject.activeSelf)
			{
				SubscribeToEvents();
			}
		}

		private static void SubscribeToEvents()
		{
			if (activateFlashlightAction != null)
			{
				activateFlashlightAction.Enable();
				activateFlashlightAction.performed += OnActivateFlashlightPerformed;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				SubscribeToEvents();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable(PlayerControllerB __instance)
		{
			if (activateFlashlightAction != null && !((Object)(object)__instance != (Object)(object)localPlayerController))
			{
				activateFlashlightAction.performed -= OnActivateFlashlightPerformed;
				activateFlashlightAction.Disable();
			}
		}

		private static void OnActivateFlashlightPerformed(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || localPlayerController.inTerminalMenu || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject))
			{
				return;
			}
			FlashlightItem mainFlashlight = Patcher.GetMainFlashlight(localPlayerController);
			if (((CallbackContext)(ref context)).performed && !((Object)(object)mainFlashlight == (Object)null))
			{
				float num = (float)Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").GetValue();
				if (!(num < 0.075f))
				{
					((GrabbableObject)mainFlashlight).UseItemOnClient(!((GrabbableObject)mainFlashlight).isBeingUsed);
					Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").SetValue((object)0);
				}
			}
		}
	}
	[BepInPlugin("FlipMods.ReservedFlashlightSlot", "ReservedFlashlightSlot", "1.5.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private Harmony _harmony;

		public static ReservedItemInfo proFlashlightInfo = new ReservedItemInfo("Pro-flashlight", 120, true, true, true, true);

		public static ReservedItemInfo flashlightInfo = new ReservedItemInfo("Flashlight", 120, true, true, true, true);

		public static ReservedItemInfo laserPointerInfo = new ReservedItemInfo("Laser pointer", 120, true, true, true, true);

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("ReservedFlashlightSlot");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ReservedFlashlightSlot loaded");
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedFlashlightSlot";

		public const string PLUGIN_NAME = "ReservedFlashlightSlot";

		public const string PLUGIN_VERSION = "1.5.5";
	}
}
namespace ReservedFlashlightSlot.Patches
{
	[HarmonyPatch]
	internal static class Patcher
	{
		private static Vector3 playerShoulderPositionOffset = new Vector3(0.2f, 0.25f, 0f);

		private static Vector3 playerShoulderRotationOffset = new Vector3(90f, 0f, 0f);

		private static string originalControlTooltip = "";

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static PlayerControllerB GetPreviousPlayerHeldBy(FlashlightItem flashlightItem)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (PlayerControllerB)Traverse.Create((object)flashlightItem).Field("previousPlayerHeldBy").GetValue();
		}

		public static FlashlightItem GetMainFlashlight(PlayerControllerB playerController)
		{
			return GetCurrentlySelectedFlashlight(playerController) ?? GetReservedFlashlight(playerController);
		}

		public static FlashlightItem GetReservedFlashlight(PlayerControllerB playerController)
		{
			return (FlashlightItem)(SyncManager.syncReservedItemsList.Contains(Plugin.flashlightInfo) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static FlashlightItem GetCurrentlySelectedFlashlight(PlayerControllerB playerController)
		{
			return (FlashlightItem)((playerController.currentItemSlot >= 0 && playerController.currentItemSlot < playerController.ItemSlots.Length) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static bool IsFlashlightOn(PlayerControllerB playerController)
		{
			return ((GrabbableObject)(GetMainFlashlight(playerController)?)).isBeingUsed ?? false;
		}

		[HarmonyPatch(typeof(FlashlightItem), "__initializeVariables")]
		[HarmonyPostfix]
		public static void EditTooltips(FlashlightItem __instance)
		{
			if (originalControlTooltip == "")
			{
				originalControlTooltip = ((GrabbableObject)__instance).itemProperties.toolTips[((GrabbableObject)__instance).itemProperties.toolTips.Length - 1];
			}
			((GrabbableObject)__instance).itemProperties.toolTips[((GrabbableObject)__instance).itemProperties.toolTips.Length - 1] = $"{originalControlTooltip}[{ConfigSettings.activateFlashlightDisplayName.ToUpper()}]";
		}

		[HarmonyPatch(typeof(MenuManager), "OnEnable")]
		[HarmonyPostfix]
		public static void ResetVariables()
		{
			Keybinds.localPlayerController = null;
		}

		[HarmonyPatch(typeof(FlashlightItem), "SwitchFlashlight")]
		[HarmonyPostfix]
		public static void OnSwitchOnOffFlashlight(bool on, FlashlightItem __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				UpdateAllFlashlightStates(((GrabbableObject)__instance).playerHeldBy, on);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketItem")]
		[HarmonyPostfix]
		public static void OnPocketFlashlightLocal(FlashlightItem __instance)
		{
			OnPocketFlashlight(__instance, ((GrabbableObject)__instance).isBeingUsed);
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketFlashlightClientRpc")]
		[HarmonyPrefix]
		public static void OnPocketFlashlightClientRpc(bool stillUsingFlashlight, FlashlightItem __instance)
		{
			if (NetworkHelper.IsValidClientRpcExecStage((NetworkBehaviour)(object)__instance) && !((NetworkBehaviour)__instance).IsOwner && !((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) && !((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController))
			{
				OnPocketFlashlight(__instance, stillUsingFlashlight);
			}
		}

		private static void OnPocketFlashlight(FlashlightItem flashlightItem, bool stillUsingFlashlight = false)
		{
			if (!((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)null))
			{
				FlashlightItem currentlySelectedFlashlight = GetCurrentlySelectedFlashlight(((GrabbableObject)flashlightItem).playerHeldBy);
				FlashlightItem reservedFlashlight = GetReservedFlashlight(((GrabbableObject)flashlightItem).playerHeldBy);
				bool mainFlashlightActive = stillUsingFlashlight || ((Object)(object)currentlySelectedFlashlight != (Object)null && ((GrabbableObject)currentlySelectedFlashlight).isBeingUsed);
				if ((Object)(object)currentlySelectedFlashlight != (Object)null && ((GrabbableObject)currentlySelectedFlashlight).isBeingUsed)
				{
					((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = null;
				}
				else if (((GrabbableObject)flashlightItem).isBeingUsed)
				{
					((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)flashlightItem;
				}
				else if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight == (Object)null || !((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight.isBeingUsed))
				{
					((GrabbableObject)flashlightItem).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
				}
				Renderer[] componentsInChildren = ((Component)flashlightItem).GetComponentsInChildren<Renderer>();
				foreach (Renderer val in componentsInChildren)
				{
					((Component)val).gameObject.layer = (((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)(object)localPlayerController) ? 23 : 6);
				}
				if ((Object)(object)flashlightItem == (Object)(object)reservedFlashlight)
				{
					((GrabbableObject)flashlightItem).parentObject = ((GrabbableObject)flashlightItem).playerHeldBy.playerGlobalHead.parent;
				}
				UpdateAllFlashlightStates(((GrabbableObject)flashlightItem).playerHeldBy, mainFlashlightActive);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "EquipItem")]
		[HarmonyPostfix]
		public static void OnEquipFlashlight(FlashlightItem __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				bool mainFlashlightActive = ((Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight != (Object)null && ((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight.isBeingUsed) || ((GrabbableObject)__instance).isBeingUsed;
				FlashlightItem reservedFlashlight = GetReservedFlashlight(((GrabbableObject)__instance).playerHeldBy);
				if (((GrabbableObject)__instance).isBeingUsed || (Object)(object)__instance == (Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight)
				{
					((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight = null;
				}
				else if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight == (Object)null || !((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight.isBeingUsed))
				{
					((GrabbableObject)__instance).playerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
				}
				Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
				foreach (Renderer val in componentsInChildren)
				{
					((Component)val).gameObject.layer = 6;
				}
				((GrabbableObject)__instance).parentObject = (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController) ? ((GrabbableObject)__instance).playerHeldBy.localItemHolder : ((GrabbableObject)__instance).playerHeldBy.serverItemHolder);
				UpdateAllFlashlightStates(((GrabbableObject)__instance).playerHeldBy, mainFlashlightActive);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "DiscardItem")]
		[HarmonyPrefix]
		public static void ResetPocketedFlashlight(FlashlightItem __instance)
		{
			PlayerControllerB previousPlayerHeldBy = GetPreviousPlayerHeldBy(__instance);
			if (!((Object)(object)previousPlayerHeldBy == (Object)null))
			{
				FlashlightItem reservedFlashlight = GetReservedFlashlight(previousPlayerHeldBy);
				if ((Object)(object)reservedFlashlight != (Object)null && ((Object)(object)__instance == (Object)(object)previousPlayerHeldBy.pocketedFlashlight || (Object)(object)previousPlayerHeldBy.pocketedFlashlight == (Object)null))
				{
					previousPlayerHeldBy.pocketedFlashlight = (GrabbableObject)(object)reservedFlashlight;
				}
				Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
				foreach (Renderer val in componentsInChildren)
				{
					((Component)val).gameObject.layer = 6;
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void SetPositionOffset(GrabbableObject __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is FlashlightItem && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance.parentObject != (Object)null && __instance.isPocketed && (Object)(object)__instance == (Object)(object)GetReservedFlashlight(__instance.playerHeldBy) && (Object)(object)__instance != (Object)(object)GetCurrentlySelectedFlashlight(__instance.playerHeldBy))
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = ((Component)__instance.parentObject).transform.rotation * Quaternion.Euler(playerShoulderRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * playerShoulderPositionOffset;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EnableItemMeshes")]
		[HarmonyPrefix]
		public static void OnEnableItemMeshes(ref bool enable, GrabbableObject __instance)
		{
			if (__instance is FlashlightItem && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance == (Object)(object)GetReservedFlashlight(__instance.playerHeldBy) && !ConfigSettings.hideFlashlightMeshShoulder.Value)
			{
				enable = true;
			}
		}

		private static void UpdateAllFlashlightStates(PlayerControllerB playerController, bool mainFlashlightActive = true)
		{
			FlashlightItem mainFlashlight = GetMainFlashlight(playerController);
			if ((Object)(object)mainFlashlight == (Object)null)
			{
				((Behaviour)playerController.helmetLight).enabled = false;
				mainFlashlightActive = false;
			}
			else
			{
				playerController.ChangeHelmetLight(mainFlashlight.flashlightTypeID, mainFlashlightActive && (Object)(object)playerController == (Object)(object)localPlayerController && (Object)(object)playerController.ItemSlots[playerController.currentItemSlot] != (Object)(object)mainFlashlight);
			}
			for (int i = 0; i < PlayerPatcher.combinedHotbarSize; i++)
			{
				GrabbableObject obj = playerController.ItemSlots[i];
				FlashlightItem val = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					UpdateFlashlightState(val, (Object)(object)val == (Object)(object)mainFlashlight && mainFlashlightActive);
				}
			}
		}

		private static void UpdateFlashlightState(FlashlightItem flashlightItem, bool active)
		{
			if (!((Object)(object)((GrabbableObject)flashlightItem).playerHeldBy == (Object)null))
			{
				PlayerControllerB playerHeldBy = ((GrabbableObject)flashlightItem).playerHeldBy;
				((GrabbableObject)flashlightItem).isBeingUsed = active;
				bool flag = (Object)(object)playerHeldBy != (Object)(object)localPlayerController || (Object)(object)playerHeldBy.ItemSlots[playerHeldBy.currentItemSlot] == (Object)(object)flashlightItem;
				((Behaviour)flashlightItem.flashlightBulb).enabled = active && flag;
				((Behaviour)flashlightItem.flashlightBulbGlow).enabled = active && flag;
				flashlightItem.usingPlayerHelmetLight = active && !flag;
			}
		}
	}
}

BepInEx/plugins/ReservedItemSlotCore.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using ReservedItemSlotCore.Config;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedItemSlotCore")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedItemSlotCore")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("238ce080-e339-46b6-9b08-992a950453a1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("ReservedFlashlightSlot")]
[assembly: InternalsVisibleTo("ReservedWalkieSlot")]
[assembly: InternalsVisibleTo("ReservedBoomboxSlot")]
[assembly: InternalsVisibleTo("ReservedPersonalBoomboxSlot")]
[assembly: InternalsVisibleTo("ReservedSprayPaintSlot")]
[assembly: InternalsVisibleTo("ReservedWeaponSlot")]
[assembly: InternalsVisibleTo("ReservedUtilitySlot")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedItemSlotCore
{
	internal class ReservedPlayerData
	{
		public ReservedItemInfo grabbingReservedItem = null;

		public int previousHotbarIndex = -1;

		public bool inReservedHotbarSlots = false;

		public int reservedHotbarStartIndex = 4;
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static PlayerControllerB localPlayerController;

		public static InputAction focusReservedHotbarAction;

		public static InputAction rawScrollAction;

		public static bool holdingModifierKey;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void OnLocalPlayerConnect(PlayerControllerB __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			localPlayerController = __instance;
			focusReservedHotbarAction = new InputAction((string)null, (InputActionType)0, ConfigSettings.focusReservedHotbarHotkey.Value, (string)null, (string)null, (string)null);
			rawScrollAction = new InputAction("Scroll", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null);
			if (((Component)localPlayerController).gameObject.activeSelf)
			{
				SubscribeToEvents();
			}
		}

		private static void SubscribeToEvents()
		{
			focusReservedHotbarAction.performed += FocusReservedHotbarSlotsAction;
			if (!ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				focusReservedHotbarAction.canceled += UnfocusReservedHotbarSlotsPerformed;
			}
			focusReservedHotbarAction.Enable();
			rawScrollAction.Enable();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
		[HarmonyPrefix]
		public static void OnEnable(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				SubscribeToEvents();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
		[HarmonyPrefix]
		public static void OnDisable(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)localPlayerController))
			{
				focusReservedHotbarAction.performed -= FocusReservedHotbarSlotsAction;
				if (!ConfigSettings.toggleFocusReservedHotbar.Value)
				{
					focusReservedHotbarAction.canceled -= UnfocusReservedHotbarSlotsPerformed;
				}
				focusReservedHotbarAction.Disable();
				rawScrollAction.Disable();
			}
		}

		private static void FocusReservedHotbarSlotsAction(CallbackContext context)
		{
			if (SyncManager.numReservedItemSlots <= 0 || (Object)(object)localPlayerController == (Object)null || !((NetworkBehaviour)localPlayerController).IsOwner || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject))
			{
				return;
			}
			if (!ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				holdingModifierKey = true;
			}
			if (((CallbackContext)(ref context)).performed && ReservedItemPatcher.CanSwapToReservedHotbarSlot())
			{
				if (!ConfigSettings.toggleFocusReservedHotbar.Value)
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(active: true);
				}
				else
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(!ReservedItemPatcher.isReservedHotbarFocused);
				}
			}
		}

		private static void UnfocusReservedHotbarSlotsPerformed(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((NetworkBehaviour)localPlayerController).IsOwner && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
			{
				holdingModifierKey = false;
				if (((CallbackContext)(ref context)).canceled && ReservedItemPatcher.CanSwapToReservedHotbarSlot())
				{
					ReservedItemPatcher.FocusReservedHotbarSlots(active: false);
				}
			}
		}
	}
	[BepInPlugin("FlipMods.ReservedItemSlotCore", "ReservedItemSlotCore", "1.7.6")]
	internal class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		public static Dictionary<string, ReservedItemInfo> reservedItemsDictDefault => ReservedItemInfo.reservedItemsDictDefault;

		public static List<ReservedItemInfo> reservedItemsListDefault => ReservedItemInfo.reservedItemsListDefault;

		public static List<ReservedItemInfo> reservedItemSlotRepsDefault => ReservedItemInfo.reservedItemSlotRepsDefault;

		public static int numReservedItemSlotsDefault => ReservedItemInfo.numReservedItemSlotsDefault;

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			instance = this;
			_harmony = new Harmony("ReservedItemSlotCore");
			ConfigSettings.BindConfigSettings();
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ReservedItemSlotCore loaded");
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		public static bool IsReservedItemDefault(string itemName)
		{
			return reservedItemsDictDefault.ContainsKey(itemName);
		}

		public static ReservedItemInfo GetReservedItemInfoDefault(string itemName)
		{
			return IsReservedItemDefault(itemName) ? reservedItemsDictDefault[itemName] : null;
		}

		public static ReservedItemInfo GetReservedItemInfoDefault(GrabbableObject item)
		{
			return ((Object)(object)item != (Object)null) ? GetReservedItemInfoDefault(item.itemProperties.itemName) : null;
		}

		public static int GetReservedItemHotbarIndex(string itemName)
		{
			return IsReservedItemDefault(itemName) ? reservedItemsDictDefault[itemName].indexInInventory : (-1);
		}
	}
	internal class ReservedItemInfo
	{
		public static Dictionary<string, ReservedItemInfo> reservedItemsDictDefault = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemsListDefault = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemSlotRepsDefault = new List<ReservedItemInfo>();

		public static Dictionary<string, ReservedItemInfo> reservedItemsDict = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemsList = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> reservedItemSlotReps = new List<ReservedItemInfo>();

		public string itemName = "";

		public HashSet<string> acceptedItemNames;

		public int hotbarSlotPriority = 0;

		public int reservedItemIndex = 0;

		public bool forceUpdateCanBeGrabbedBeforeGameStart = false;

		public bool canBeGrabbedBeforeGameStart = false;

		public bool forceUpdateRequiresBattery = false;

		public bool requiresBattery = false;

		public static int numReservedItemSlotsDefault => reservedItemSlotRepsDefault.Count;

		public int indexInInventory => ((Object)(object)PlayerPatcher.localPlayerController != (Object)null) ? (PlayerPatcher.reservedItemsStartIndex + reservedItemIndex) : (-1);

		public ReservedItemInfo()
		{
		}

		public ReservedItemInfo(string itemName, int hotbarSlotPriority, bool forceUpdateCanBeGrabbedBeforeGameStart = false, bool canBeGrabbedBeforeGameStart = false, bool forceUpdateRequiresBattery = false, bool requiresBattery = false)
		{
			this.itemName = itemName;
			this.hotbarSlotPriority = hotbarSlotPriority;
			AddItemInfoToList(this);
			ReservedItemInfo info = new ReservedItemInfo(this);
			AddItemInfoToList(info, reservedItemsListDefault, reservedItemsDictDefault, reservedItemSlotRepsDefault);
		}

		public static void AddItemInfoToList(ReservedItemInfo info, List<ReservedItemInfo> _reservedItemsList = null, Dictionary<string, ReservedItemInfo> _reservedItemsDict = null, List<ReservedItemInfo> _reservedItemSlotReps = null)
		{
			if (_reservedItemsList == null)
			{
				_reservedItemsList = reservedItemsList;
			}
			if (_reservedItemsDict == null)
			{
				_reservedItemsDict = reservedItemsDict;
			}
			if (_reservedItemSlotReps == null)
			{
				_reservedItemSlotReps = reservedItemSlotReps;
			}
			if (!_reservedItemsDict.ContainsKey(info.itemName))
			{
				_reservedItemsDict.Add(info.itemName, info);
				_reservedItemsList.Add(info);
				int i;
				for (i = 0; i < _reservedItemSlotReps.Count; i++)
				{
					ReservedItemInfo reservedItemInfo = _reservedItemSlotReps[i];
					if (info.hotbarSlotPriority >= reservedItemInfo.hotbarSlotPriority)
					{
						break;
					}
				}
				info.reservedItemIndex = i;
				if (i == _reservedItemSlotReps.Count || info.hotbarSlotPriority != _reservedItemSlotReps[i].hotbarSlotPriority)
				{
					info.acceptedItemNames = new HashSet<string> { info.itemName };
					_reservedItemSlotReps.Insert(i, info);
					{
						foreach (ReservedItemInfo _reservedItems in _reservedItemsList)
						{
							if (info != _reservedItems && _reservedItems.reservedItemIndex >= i)
							{
								_reservedItems.reservedItemIndex++;
							}
						}
						return;
					}
				}
				info.acceptedItemNames = _reservedItemSlotReps[i].acceptedItemNames;
				info.acceptedItemNames.Add(info.itemName);
			}
			else
			{
				Plugin.Log($"Tried to add duplicate item name to the ReservedItems list: {info.itemName}. Sorting instead");
			}
		}

		public ReservedItemInfo(ReservedItemInfo copyFrom)
		{
			itemName = copyFrom.itemName;
			hotbarSlotPriority = copyFrom.hotbarSlotPriority;
			reservedItemIndex = copyFrom.reservedItemIndex;
			forceUpdateCanBeGrabbedBeforeGameStart = copyFrom.forceUpdateCanBeGrabbedBeforeGameStart;
			canBeGrabbedBeforeGameStart = copyFrom.canBeGrabbedBeforeGameStart;
			forceUpdateRequiresBattery = copyFrom.forceUpdateRequiresBattery;
			requiresBattery = copyFrom.requiresBattery;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedItemSlotCore";

		public const string PLUGIN_NAME = "ReservedItemSlotCore";

		public const string PLUGIN_VERSION = "1.7.6";
	}
}
namespace ReservedItemSlotCore.Config
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> focusReservedHotbarHotkey;

		public static ConfigEntry<bool> toggleFocusReservedHotbar;

		public static ConfigEntry<bool> preventReservedItemSlotFade;

		public static string focusReservedHotbarHotkeyDisplayName;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			focusReservedHotbarHotkey = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedItemSlotCore", "FocusReservedItemSlotsHotkey", "<Keyboard>/leftAlt", "Which key will focus your reserved item slots hotbar to allow selcting, dropping, charging, etc.");
			toggleFocusReservedHotbar = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedItemSlotCore", "ToggleFocusReservedHotbar", false, "If set to true, swapping to the reserved hotbar slots will be toggled when pressing the hotkey rather than while holding the hotkey. Setting this option to true may have bugs at this current time.");
			preventReservedItemSlotFade = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedItemSlotCore", "PreventReservedHotbarSlotFade", false, "If true, the reserved hotbar slots will not fade with the rest of the default slots.");
			focusReservedHotbarHotkeyDisplayName = GetDisplayName(focusReservedHotbarHotkey.Value);
			currentConfigEntries.Add(((ConfigEntryBase)focusReservedHotbarHotkey).Definition.Key, (ConfigEntryBase)(object)focusReservedHotbarHotkey);
			currentConfigEntries.Add(((ConfigEntryBase)toggleFocusReservedHotbar).Definition.Key, (ConfigEntryBase)(object)toggleFocusReservedHotbar);
			currentConfigEntries.Add(((ConfigEntryBase)preventReservedItemSlotFade).Definition.Key, (ConfigEntryBase)(object)preventReservedItemSlotFade);
			TryRemoveOldConfigSettings();
		}

		public static string GetDisplayName(string key)
		{
			key = key.Replace("<Keyboard>/", "");
			key = key.Replace("<Mouse>/", "");
			string text = key;
			text = text.Replace("leftAlt", "Alt");
			text = text.Replace("rightAlt", "Alt");
			text = text.Replace("leftCtrl", "Ctrl");
			text = text.Replace("rightCtrl", "Ctrl");
			text = text.Replace("leftShift", "Shift");
			text = text.Replace("rightShift", "Shift");
			text = text.Replace("leftButton", "LMB");
			text = text.Replace("rightButton", "RMB");
			return text.Replace("middleButton", "MMB");
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
}
namespace ReservedItemSlotCore.Networking
{
	public static class NetworkHelper
	{
		private static int NONE_EXEC_STAGE = 0;

		private static int SERVER_EXEC_STAGE = 1;

		private static int CLIENT_EXEC_STAGE = 2;

		public static int GetExecStage(NetworkBehaviour __instance)
		{
			return (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
		}

		public static bool IsClientExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == CLIENT_EXEC_STAGE;
		}

		public static bool IsServerExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == SERVER_EXEC_STAGE;
		}

		public static bool IsValidClientRpcExecStage(NetworkBehaviour __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				return false;
			}
			int num = (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
			if ((singleton.IsServer || singleton.IsHost) && num != 2)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class SyncManager
	{
		public static PlayerControllerB localPlayerController;

		public static Dictionary<string, ReservedItemInfo> syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();

		public static List<ReservedItemInfo> syncReservedItemsList = new List<ReservedItemInfo>();

		public static List<ReservedItemInfo> syncReservedItemSlotReps = new List<ReservedItemInfo>();

		public static bool isSynced = false;

		public static int numReservedItemSlots => syncReservedItemSlotReps.Count;

		public static bool IsReservedItem(string itemName)
		{
			return syncReservedItemsDict.ContainsKey(itemName);
		}

		public static ReservedItemInfo GetReservedItemInfo(string itemName)
		{
			return IsReservedItem(itemName) ? syncReservedItemsDict[itemName] : null;
		}

		public static ReservedItemInfo GetReservedItemInfo(GrabbableObject item)
		{
			return ((Object)(object)item != (Object)null) ? GetReservedItemInfo(item.itemProperties.itemName) : null;
		}

		public static int GetReservedItemHotbarIndex(string itemName)
		{
			return IsReservedItem(itemName) ? syncReservedItemsDict[itemName].indexInInventory : (-1);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init(PlayerControllerB __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			localPlayerController = __instance;
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-OnSwapHotbarClientRpc", new HandleNamedMessageDelegate(OnSwapHotbarClientRpc));
			if (NetworkManager.Singleton.IsServer)
			{
				isSynced = true;
				syncReservedItemsDict = ReservedItemInfo.reservedItemsDict;
				syncReservedItemsList = ReservedItemInfo.reservedItemsList;
				syncReservedItemSlotReps = ReservedItemInfo.reservedItemSlotReps;
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-OnSwapHotbarServerRpc", new HandleNamedMessageDelegate(OnSwapHotbarServerRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-RequestSyncServerRpc", new HandleNamedMessageDelegate(RequestSyncServerRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-RequestSyncClientRpc", new HandleNamedMessageDelegate(RequestSyncClientRpc));
				{
					foreach (ReservedItemInfo syncReservedItems in syncReservedItemsList)
					{
						ReservedItemInfo reservedItemInfo = ReservedItemInfo.reservedItemsDictDefault[syncReservedItems.itemName];
						syncReservedItems.hotbarSlotPriority = reservedItemInfo.hotbarSlotPriority;
						syncReservedItems.reservedItemIndex = reservedItemInfo.reservedItemIndex;
					}
					return;
				}
			}
			isSynced = false;
			syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();
			syncReservedItemsList = new List<ReservedItemInfo>();
			syncReservedItemSlotReps = new List<ReservedItemInfo>();
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("ReservedItemSlots-RequestSyncClientRpc", new HandleNamedMessageDelegate(RequestSyncClientRpc));
			RequestSyncWithServer();
		}

		private static void RequestSyncWithServer()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Requesting sync with server");
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-RequestSyncServerRpc", 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)3);
			}
		}

		private static void RequestSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			Plugin.Log("Receiving sync request from client: " + clientId);
			int num = 4 * syncReservedItemsList.Count;
			foreach (ReservedItemInfo syncReservedItems in syncReservedItemsList)
			{
				num += 4 + 2 * syncReservedItems.itemName.Length;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, -1);
			int count = syncReservedItemsList.Count;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
			foreach (ReservedItemInfo syncReservedItems2 in syncReservedItemsList)
			{
				count = syncReservedItems2.itemName.Length;
				((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
				string itemName = syncReservedItems2.itemName;
				for (int i = 0; i < itemName.Length; i++)
				{
					char c = itemName[i];
					((FastBufferWriter)(ref val)).WriteValue<char>(ref c, default(ForPrimitives));
				}
				((FastBufferWriter)(ref val)).WriteValue<int>(ref syncReservedItems2.hotbarSlotPriority, default(ForPrimitives));
			}
			Plugin.Log("Sent sync to client.");
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-RequestSyncClientRpc", clientId, val, (NetworkDelivery)3);
		}

		private static void RequestSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
			{
				return;
			}
			isSynced = true;
			syncReservedItemsDict = new Dictionary<string, ReservedItemInfo>();
			syncReservedItemsList = new List<ReservedItemInfo>();
			syncReservedItemSlotReps = new List<ReservedItemInfo>();
			Plugin.Log("Receiving sync from server.");
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			char c = default(char);
			for (int i = 0; i < num; i++)
			{
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
				((FastBufferReader)(ref reader)).TryBeginRead(2 * num2);
				string text = "";
				for (int j = 0; j < num2; j++)
				{
					((FastBufferReader)(ref reader)).ReadValue<char>(ref c, default(ForPrimitives));
					text += c;
				}
				bool flag = ReservedItemInfo.reservedItemsDict.ContainsKey(text);
				ReservedItemInfo reservedItemInfo = (ReservedItemInfo.reservedItemsDict.ContainsKey(text) ? ReservedItemInfo.reservedItemsDict[text] : new ReservedItemInfo
				{
					itemName = text
				});
				((FastBufferReader)(ref reader)).ReadValue<int>(ref reservedItemInfo.hotbarSlotPriority, default(ForPrimitives));
				Plugin.Log("Receiving sync for item: - Item: " + reservedItemInfo.itemName + " Prio: " + reservedItemInfo.hotbarSlotPriority);
				ReservedItemInfo.AddItemInfoToList(reservedItemInfo, syncReservedItemsList, syncReservedItemsDict, syncReservedItemSlotReps);
			}
			Plugin.Log("Received sync for " + syncReservedItemSlotReps.Count + " reserved item slots. (" + syncReservedItemsList.Count + " items total)");
		}

		private static void SendSwapHotbarUpdate(int hotbarSlot)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValue<int>(ref hotbarSlot, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReservedItemSlots-OnSwapHotbarServerRpc", 0uL, val, (NetworkDelivery)3);
			}
		}

		private static void OnSwapHotbarServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsServer)
			{
				if (((FastBufferReader)(ref reader)).TryBeginRead(4))
				{
					int hotbarSlot = default(int);
					((FastBufferReader)(ref reader)).ReadValue<int>(ref hotbarSlot, default(ForPrimitives));
					Plugin.Log("Receiving request for hotbar swap. Slot: " + hotbarSlot + " ClientId: " + clientId);
					FastBufferWriter val = default(FastBufferWriter);
					((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref hotbarSlot, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref clientId, default(ForPrimitives));
					TryUpdateClientHotbarSlot(clientId, hotbarSlot);
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("ReservedItemSlots-OnSwapHotbarClientRpc", val, (NetworkDelivery)3);
				}
				else
				{
					Plugin.Log("Failed to receive hotbar swap index from Client: " + clientId);
				}
			}
		}

		private static void OnSwapHotbarClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_003a: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
			{
				return;
			}
			if (((FastBufferReader)(ref reader)).TryBeginRead(12))
			{
				int hotbarSlot = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref hotbarSlot, default(ForPrimitives));
				ulong num = default(ulong);
				((FastBufferReader)(ref reader)).ReadValue<ulong>(ref num, default(ForPrimitives));
				Plugin.Log("Receiving update for hotbar swap. Slot: " + hotbarSlot + " ClientId: " + num);
				if (num != localPlayerController.actualClientId && !TryUpdateClientHotbarSlot(num, hotbarSlot))
				{
					Plugin.Log("Failed to receive hotbar swap index from Client: " + num);
				}
			}
			else
			{
				Plugin.Log("Failed to receive hotbar swap index from Client");
			}
		}

		private static bool TryUpdateClientHotbarSlot(ulong clientId, int hotbarSlot, int reservedItemsStartIndex = -1)
		{
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if (val.actualClientId == clientId)
				{
					CallSwitchToItemSlotMethod(val, hotbarSlot);
					return true;
				}
			}
			return false;
		}

		public static void SwapHotbarSlot(int hotbarIndex)
		{
			SendSwapHotbarUpdate(hotbarIndex);
			CallSwitchToItemSlotMethod(localPlayerController, hotbarIndex);
		}

		private static void CallSwitchToItemSlotMethod(PlayerControllerB playerController, int hotbarIndex)
		{
			if (hotbarIndex < playerController.ItemSlots.Length)
			{
				ShipBuildModeManager.Instance.CancelBuildMode(true);
				ReservedItemPatcher.SwitchToItemSlot(playerController, hotbarIndex);
				if ((Object)(object)playerController.currentlyHeldObjectServer != (Object)null)
				{
					((Component)playerController.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(playerController.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f);
				}
			}
		}
	}
}
namespace ReservedItemSlotCore.Patches
{
	[HarmonyPatch]
	public static class HUDPatcher
	{
		private static CanvasScaler canvasScaler;

		private static AspectRatioFitter aspectRatioFitter;

		private static float iconWidth;

		private static float xPos;

		public static int startIndexReservedItemSlots;

		[HarmonyPatch(typeof(HUDManager), "Awake")]
		[HarmonyPrefix]
		public static void Initialize(HUDManager __instance)
		{
			//IL_0032: 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)
			canvasScaler = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<CanvasScaler>();
			aspectRatioFitter = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<AspectRatioFitter>();
			iconWidth = ((Component)__instance.itemSlotIconFrames[0]).GetComponent<RectTransform>().sizeDelta.x;
			xPos = canvasScaler.referenceResolution.x / 2f / aspectRatioFitter.aspectRatio - iconWidth / 4f;
		}

		public static void AddNewHotbarSlotsHud()
		{
			//IL_0048: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerPatcher.reservedHotbarSize <= 0)
			{
				return;
			}
			List<Image> list = new List<Image>(HUDManager.Instance.itemSlotIconFrames);
			List<Image> list2 = new List<Image>(HUDManager.Instance.itemSlotIcons);
			float y = ((Component)HUDManager.Instance.itemSlotIconFrames[0]).GetComponent<RectTransform>().sizeDelta.y;
			Vector3 eulerAngles = ((Transform)((Component)HUDManager.Instance.itemSlotIconFrames[0]).GetComponent<RectTransform>()).eulerAngles;
			Vector3 eulerAngles2 = ((Transform)((Component)HUDManager.Instance.itemSlotIcons[0]).GetComponent<RectTransform>()).eulerAngles;
			Plugin.Log($"Adding {SyncManager.syncReservedItemSlotReps.Count} Reserved item slots to the inventory HUD. Previous inventory HUD size: {PlayerPatcher.reservedItemsStartIndex}");
			for (int i = 0; i < SyncManager.syncReservedItemSlotReps.Count; i++)
			{
				ReservedItemInfo reservedItemInfo = SyncManager.syncReservedItemSlotReps[i];
				Plugin.Log($"Adding Reserved item slot for item types [{reservedItemInfo.itemName}]. Inventory index: {list.Count}");
				float num = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + 1.125f * y * (float)i;
				Image val = Object.Instantiate<Image>(HUDManager.Instance.itemSlotIconFrames[PlayerPatcher.reservedItemsStartIndex - 1], ((Component)HUDManager.Instance.itemSlotIconFrames[0]).transform.parent);
				((Object)val).name = $"ReservedItemSlot{i} [{reservedItemInfo.itemName}]";
				((Graphic)val).rectTransform.anchoredPosition = new Vector2(xPos, num);
				((Transform)((Graphic)val).rectTransform).eulerAngles = eulerAngles;
				CanvasGroup val2 = ((Component)val).gameObject.AddComponent<CanvasGroup>();
				val2.ignoreParentGroups = ConfigSettings.preventReservedItemSlotFade.Value;
				val2.alpha = 1f;
				Image component = ((Component)((Component)val).transform.GetChild(0)).GetComponent<Image>();
				((Object)component).name = "Icon";
				((Transform)((Graphic)component).rectTransform).eulerAngles = eulerAngles2;
				list.Add(val);
				list2.Add(component);
			}
			if (SyncManager.numReservedItemSlots > 0)
			{
				TextMeshProUGUI component2 = new GameObject("ReservedItemSlotTooltip", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				}).GetComponent<TextMeshProUGUI>();
				RectTransform rectTransform = ((TMP_Text)component2).rectTransform;
				((Component)rectTransform).transform.parent = ((Component)list[PlayerPatcher.reservedItemsStartIndex]).transform;
				((Transform)rectTransform).localScale = Vector3.one;
				rectTransform.sizeDelta = new Vector2(((Graphic)list[0]).rectTransform.sizeDelta.x * 2f, 10f);
				rectTransform.pivot = Vector2.one / 2f;
				rectTransform.anchoredPosition3D = new Vector3(0f, (0f - rectTransform.sizeDelta.x / 2f) * 1.2f, 0f);
				((TMP_Text)component2).font = ((TMP_Text)HUDManager.Instance.controlTipLines[0]).font;
				((TMP_Text)component2).fontSize = 7f;
				((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
				if (!ConfigSettings.toggleFocusReservedHotbar.Value)
				{
					((TMP_Text)component2).text = string.Format($"Hold: [{ConfigSettings.GetDisplayName(ConfigSettings.focusReservedHotbarHotkey.Value)}]");
				}
				else
				{
					((TMP_Text)component2).text = string.Format($"Toggle: [{ConfigSettings.GetDisplayName(ConfigSettings.focusReservedHotbarHotkey.Value)}]");
				}
			}
			HUDManager.Instance.itemSlotIconFrames = list.ToArray();
			HUDManager.Instance.itemSlotIcons = list2.ToArray();
			Plugin.Log($"Finished adding {PlayerPatcher.reservedHotbarSize} Reserved Item slots in the inventory HUD.");
		}

		public static void UpdateHUD()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < PlayerPatcher.reservedHotbarSize; i++)
			{
				int num = PlayerPatcher.reservedItemsStartIndex + i;
				float num2 = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + 1.125f * iconWidth * (float)i;
				((Graphic)HUDManager.Instance.itemSlotIconFrames[num]).rectTransform.anchoredPosition = new Vector2(xPos, num2);
			}
		}
	}
	[HarmonyPatch]
	public static class ReservedItemPatcher
	{
		public static bool isReservedHotbarFocused = false;

		public static int indexUnfocusedReservedHotbar = 0;

		public static int indexFocusedReservedHotbar = 0;

		internal static Dictionary<PlayerControllerB, ReservedItemInfo> grabbingReservedItemInfoDict = new Dictionary<PlayerControllerB, ReservedItemInfo>();

		internal static Dictionary<PlayerControllerB, int> previousInventoryIndexDict = new Dictionary<PlayerControllerB, int>();

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static int reservedItemsStartIndex => PlayerPatcher.reservedItemsStartIndex;

		public static int reservedHotbarSize => SyncManager.numReservedItemSlots;

		internal static ReservedItemInfo grabbingReservedItemInfoLocal
		{
			get
			{
				return ((Object)(object)localPlayerController != (Object)null) ? grabbingReservedItemInfoDict[localPlayerController] : null;
			}
			set
			{
				if (!((Object)(object)localPlayerController == (Object)null))
				{
					grabbingReservedItemInfoDict[localPlayerController] = value;
				}
			}
		}

		internal static int previousInventoryIndexLocal
		{
			get
			{
				return ((Object)(object)localPlayerController != (Object)null) ? previousInventoryIndexDict[localPlayerController] : (-1);
			}
			set
			{
				if (!((Object)(object)localPlayerController == (Object)null))
				{
					previousInventoryIndexDict[localPlayerController] = value;
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void InitSession(StartOfRound __instance)
		{
			grabbingReservedItemInfoDict.Clear();
			previousInventoryIndexDict.Clear();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		public static void InitPlayer(PlayerControllerB __instance)
		{
			grabbingReservedItemInfoDict[__instance] = null;
			previousInventoryIndexDict[__instance] = -1;
		}

		private static GrabbableObject GetCurrentlyGrabbingObject(PlayerControllerB playerController)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (GrabbableObject)Traverse.Create((object)playerController).Field("currentlyGrabbingObject").GetValue();
		}

		private static void SetCurrentlyGrabbingObject(PlayerControllerB playerController, GrabbableObject grabbable)
		{
			Traverse.Create((object)playerController).Field("currentlyGrabbingObject").SetValue((object)grabbable);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPrefix]
		public static bool GrabReservedItemPrefix(PlayerControllerB __instance)
		{
			//IL_0078: 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)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncManager.isSynced)
			{
				return true;
			}
			grabbingReservedItemInfoLocal = null;
			previousInventoryIndexLocal = -1;
			if (isReservedHotbarFocused && !ConfigSettings.toggleFocusReservedHotbar.Value)
			{
				return false;
			}
			if (__instance.twoHanded || __instance.sinkingValue > 0.73f)
			{
				return true;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, __instance.grabDistance, PlayerPatcher.INTERACTABLE_OBJECT_MASK) && ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer != 8 && ((Component)((RaycastHit)(ref val2)).collider).tag == "PhysicsProp")
			{
				GrabbableObject component = ((Component)((Component)((RaycastHit)(ref val2)).collider).transform).gameObject.GetComponent<GrabbableObject>();
				if ((Object)(object)component != (Object)null && !__instance.inSpecialInteractAnimation && !component.isHeld && !component.isPocketed)
				{
					NetworkObject networkObject = ((NetworkBehaviour)component).NetworkObject;
					if ((Object)(object)networkObject != (Object)null && networkObject.IsSpawned)
					{
						grabbingReservedItemInfoLocal = SyncManager.GetReservedItemInfo(((Component)((Component)((RaycastHit)(ref val2)).collider).transform).gameObject.GetComponent<GrabbableObject>());
						previousInventoryIndexLocal = __instance.currentItemSlot;
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPostfix]
		public static void GrabReservedItemPostfix(PlayerControllerB __instance)
		{
			if (grabbingReservedItemInfoLocal != null)
			{
				SetSpecialGrabAnimationBool(__instance, setTrue: false);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPrefix]
		public static void GrabReservedItemClientRpcPrefix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if (!SyncManager.isSynced || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance))
			{
				return;
			}
			NetworkObject val = default(NetworkObject);
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening && grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
			{
				GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>();
				ReservedItemInfo reservedItemInfo = SyncManager.GetReservedItemInfo(component);
				if (reservedItemInfo != null && IsItemSlotEmpty(reservedItemInfo, __instance))
				{
					grabbingReservedItemInfoDict[__instance] = reservedItemInfo;
					previousInventoryIndexDict[__instance] = __instance.currentItemSlot;
					return;
				}
			}
			grabbingReservedItemInfoDict[__instance] = null;
			previousInventoryIndexDict[__instance] = -1;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPostfix]
		public static void GrabReservedItemClientRpcPostfix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if (!SyncManager.isSynced || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance) || grabbingReservedItemInfoDict[__instance] == null)
			{
				return;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening)
			{
				NetworkObject val = default(NetworkObject);
				if (grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
				{
					GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>();
					ReservedItemInfo reservedItemInfo = SyncManager.GetReservedItemInfo(component);
					if (reservedItemInfo != null)
					{
						SetSpecialGrabAnimationBool(__instance, setTrue: false);
						__instance.currentlyHeldObjectServer = __instance.ItemSlots[__instance.currentItemSlot];
						if ((Object)(object)__instance.currentlyHeldObjectServer != (Object)null)
						{
							__instance.twoHanded = __instance.currentlyHeldObjectServer.itemProperties.twoHanded;
							__instance.twoHandedAnimation = __instance.currentlyHeldObjectServer.itemProperties.twoHandedAnimation;
						}
						Traverse.Create((object)component).Field("previousPlayerHeldBy").SetValue((object)__instance);
						if ((Object)(object)__instance != (Object)(object)localPlayerController)
						{
							Plugin.Log("Grab object completed on player: " + ((Object)__instance).name);
							SwitchToItemSlot(__instance, previousInventoryIndexDict[__instance]);
							grabbingReservedItemInfoDict[__instance] = null;
							previousInventoryIndexDict[__instance] = -1;
						}
						else
						{
							((Component)HUDManager.Instance.itemSlotIconFrames[grabbingReservedItemInfoLocal.indexInInventory]).GetComponent<Animator>().SetBool("selectedSlot", false);
							((Component)HUDManager.Instance.itemSlotIconFrames[previousInventoryIndexLocal]).GetComponent<Animator>().SetBool("selectedSlot", true);
							((Component)HUDManager.Instance.itemSlotIconFrames[grabbingReservedItemInfoLocal.indexInInventory]).GetComponent<Animator>().Play("PanelLines", 0, 1f);
							((Component)HUDManager.Instance.itemSlotIconFrames[previousInventoryIndexLocal]).GetComponent<Animator>().Play("PanelEnlarge", 0, 1f);
							__instance.currentlyHeldObjectServer.EnableItemMeshes(false);
							SetSpecialGrabAnimationBool(__instance, setTrue: false);
						}
						return;
					}
				}
				else if ((Object)(object)__instance == (Object)(object)localPlayerController)
				{
					Plugin.Log("Failed to validate ReservedItemGrab by the local player. Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ".");
					Traverse.Create((object)localPlayerController).Field("grabInvalidated").SetValue((object)true);
				}
				else
				{
					Plugin.Log("Failed to validate ReservedItemGrab by player with id: " + ((Object)__instance).name + ". Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ".");
				}
			}
			grabbingReservedItemInfoDict[__instance] = null;
			previousInventoryIndexDict[__instance] = -1;
		}

		[HarmonyPatch(typeof(GrabbableObject), "GrabItemOnClient")]
		[HarmonyPrefix]
		public static void OnReservedItemGrabbed(GrabbableObject __instance)
		{
			if (grabbingReservedItemInfoLocal != null && !((Object)(object)__instance != (Object)(object)GetCurrentlyGrabbingObject(localPlayerController)))
			{
				OnLocalPlayerGrabbedReservedItem();
				__instance.PocketItem();
			}
		}

		private static void OnLocalPlayerGrabbedReservedItem()
		{
			SwitchToItemSlot(localPlayerController, previousInventoryIndexLocal);
			grabbingReservedItemInfoLocal = null;
			previousInventoryIndexLocal = -1;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "FirstEmptyItemSlot")]
		[HarmonyPostfix]
		public static void GetReservedItemSlotPlacementIndex(ref int __result, PlayerControllerB __instance)
		{
			ReservedItemInfo reservedItemInfo = grabbingReservedItemInfoDict[__instance];
			if (reservedItemInfo != null)
			{
				if (IsItemSlotEmpty(reservedItemInfo))
				{
					__result = reservedItemInfo.indexInInventory;
					return;
				}
				grabbingReservedItemInfoDict[__instance] = null;
			}
			if (__result < reservedItemsStartIndex || __result >= reservedItemsStartIndex + reservedHotbarSize)
			{
				return;
			}
			__result = -1;
			for (int i = 0; i < __instance.ItemSlots.Length; i++)
			{
				if ((i < reservedItemsStartIndex || i >= reservedItemsStartIndex + reservedHotbarSize) && (Object)(object)__instance.ItemSlots[i] == (Object)null)
				{
					__result = i;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "NextItemSlot")]
		[HarmonyPostfix]
		public static void PreventScrollingOtherHotbar(ref int __result, bool forward, PlayerControllerB __instance)
		{
			if (reservedHotbarSize <= 0)
			{
				return;
			}
			bool flag = __result >= reservedItemsStartIndex && __result < reservedItemsStartIndex + reservedHotbarSize;
			bool flag2 = __instance.currentItemSlot >= reservedItemsStartIndex && __instance.currentItemSlot < reservedItemsStartIndex + reservedHotbarSize;
			if ((Object)(object)__instance != (Object)(object)localPlayerController && ((!flag && !flag2) || (flag && flag2 && (Object)(object)__instance.ItemSlots[__result] != (Object)null)))
			{
				return;
			}
			int num = (forward ? 1 : (-1));
			__result = __instance.currentItemSlot + num;
			if (!flag2)
			{
				if (__result < 0)
				{
					__result = __instance.ItemSlots.Length - 1;
					if (__result >= reservedItemsStartIndex && __result < reservedItemsStartIndex + reservedHotbarSize)
					{
						__result = reservedItemsStartIndex - 1;
					}
				}
				else if (__result >= reservedItemsStartIndex && __result < reservedItemsStartIndex + reservedHotbarSize)
				{
					__result = (forward ? (reservedItemsStartIndex + reservedHotbarSize) : (reservedItemsStartIndex - 1));
				}
				if (__result >= __instance.ItemSlots.Length)
				{
					__result = 0;
				}
				return;
			}
			if (__result < reservedItemsStartIndex)
			{
				__result = reservedItemsStartIndex + reservedHotbarSize - 1;
			}
			else if (__result >= reservedItemsStartIndex + reservedHotbarSize)
			{
				__result = reservedItemsStartIndex;
			}
			int num2 = __result;
			while (__result != __instance.currentItemSlot && (Object)(object)__instance.ItemSlots[__result] == (Object)null)
			{
				__result += num;
				if (__result < reservedItemsStartIndex)
				{
					__result = reservedItemsStartIndex + reservedHotbarSize - 1;
				}
				else if (__result >= reservedItemsStartIndex + reservedHotbarSize)
				{
					__result = reservedItemsStartIndex;
				}
			}
			if (__result == __instance.currentItemSlot && (Object)(object)__instance.ItemSlots[__instance.currentItemSlot] == (Object)null)
			{
				__result = num2;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool PreventScrollingOneReservedItem(CallbackContext context, PlayerControllerB __instance)
		{
			if ((Object)(object)__instance != (Object)(object)localPlayerController || grabbingReservedItemInfoLocal != null || reservedHotbarSize <= 0 || !isReservedHotbarFocused || __instance.inTerminalMenu || !CanSwapToReservedHotbarSlot())
			{
				return true;
			}
			int num = 0;
			for (int i = reservedItemsStartIndex; i < reservedItemsStartIndex + reservedHotbarSize; i++)
			{
				num += (((Object)(object)localPlayerController.ItemSlots[i] != (Object)null) ? 1 : 0);
			}
			if (num == 1 && localPlayerController.currentItemSlot >= reservedItemsStartIndex && localPlayerController.currentItemSlot < reservedItemsStartIndex + reservedHotbarSize && (Object)(object)localPlayerController.ItemSlots[localPlayerController.currentItemSlot] != (Object)null)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPrefix]
		public static void RefocusReservedHotbarAfterAnimation(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)localPlayerController) && !ConfigSettings.toggleFocusReservedHotbar.Value && Keybinds.holdingModifierKey != isReservedHotbarFocused && CanSwapToReservedHotbarSlot())
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}

		public static bool CanSwapToReservedHotbarSlot()
		{
			bool flag = (bool)Traverse.Create((object)localPlayerController).Field("throwingObject").GetValue();
			return !(localPlayerController.isGrabbingObjectAnimation || localPlayerController.quickMenuManager.isMenuOpen || localPlayerController.inSpecialInteractAnimation || flag) && !localPlayerController.isTypingChat && !localPlayerController.twoHanded && !localPlayerController.activatingItem && !localPlayerController.jetpackControls && !localPlayerController.disablingJetpackControls && !localPlayerController.inTerminalMenu && !localPlayerController.isPlayerDead && !localPlayerController.performingEmote && !(GetTimeSinceSwitchingSlots(localPlayerController) < 0.3f);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "UpdateSpecialAnimationValue")]
		[HarmonyPostfix]
		public static void OnSpecialAnimationUpdate(bool specialAnimation, PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)localPlayerController) && !specialAnimation && !ConfigSettings.toggleFocusReservedHotbar.Value && isReservedHotbarFocused != Keybinds.holdingModifierKey)
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}

		public static void FocusReservedHotbarSlots(bool active)
		{
			if ((reservedHotbarSize <= 0 && active) || isReservedHotbarFocused == active)
			{
				return;
			}
			isReservedHotbarFocused = active;
			int num = localPlayerController.currentItemSlot;
			if (isReservedHotbarFocused && (num < reservedItemsStartIndex || num >= reservedItemsStartIndex + reservedHotbarSize))
			{
				if (indexFocusedReservedHotbar == -1)
				{
					indexFocusedReservedHotbar = reservedItemsStartIndex;
				}
				indexUnfocusedReservedHotbar = num;
				num = Mathf.Clamp(indexFocusedReservedHotbar, reservedItemsStartIndex, reservedItemsStartIndex + reservedHotbarSize - 1);
				if ((Object)(object)localPlayerController.ItemSlots[num] == (Object)null)
				{
					for (int i = 0; i < reservedHotbarSize; i++)
					{
						int num2 = reservedItemsStartIndex + i;
						if ((Object)(object)localPlayerController.ItemSlots[num2] != (Object)null)
						{
							num = num2;
							break;
						}
					}
				}
			}
			else if (!isReservedHotbarFocused && num >= reservedItemsStartIndex && num < reservedItemsStartIndex + reservedHotbarSize)
			{
				indexFocusedReservedHotbar = num;
				if (indexUnfocusedReservedHotbar >= reservedItemsStartIndex && indexUnfocusedReservedHotbar < reservedItemsStartIndex + reservedHotbarSize)
				{
					indexUnfocusedReservedHotbar = 0;
				}
				num = indexUnfocusedReservedHotbar;
			}
			SyncManager.SwapHotbarSlot(num);
		}

		public static bool IsItemSlotEmpty(string itemName, PlayerControllerB playerController)
		{
			return IsItemSlotEmpty(SyncManager.GetReservedItemInfo(itemName), playerController);
		}

		internal static bool IsItemSlotEmpty(ReservedItemInfo itemInfo, PlayerControllerB player = null)
		{
			if ((Object)(object)player == (Object)null)
			{
				player = localPlayerController;
			}
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			return itemInfo != null && itemInfo.indexInInventory < player.ItemSlots.Length && (Object)(object)player.ItemSlots[itemInfo.indexInInventory] == (Object)null;
		}

		public static GrabbableObject GetHeldReservedObject(string itemName, PlayerControllerB player = null)
		{
			if ((Object)(object)player == (Object)null)
			{
				player = localPlayerController;
			}
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			int reservedItemHotbarIndex = SyncManager.GetReservedItemHotbarIndex(itemName);
			return (reservedItemHotbarIndex >= 0 && reservedItemHotbarIndex < player.ItemSlots.Length && (Object)(object)player.ItemSlots[reservedItemHotbarIndex] != (Object)null) ? player.ItemSlots[reservedItemHotbarIndex] : null;
		}

		public static float GetTimeSinceSwitchingSlots(PlayerControllerB playerController)
		{
			return (float)Traverse.Create((object)playerController).Field("timeSinceSwitchingSlots").GetValue();
		}

		public static void SetTimeSinceSwitchingSlots(PlayerControllerB playerController, float value)
		{
			Traverse.Create((object)playerController).Field("timeSinceSwitchingSlots").SetValue((object)value);
		}

		public static void SetSpecialGrabAnimationBool(PlayerControllerB playerController, bool setTrue, GrabbableObject currentItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SetSpecialGrabAnimationBool", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { setTrue, currentItem });
		}

		public static void SwitchToItemSlot(PlayerControllerB playerController, int slot, GrabbableObject fillSlotWithItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { slot, fillSlotWithItem });
			SetTimeSinceSwitchingSlots(playerController, 0f);
		}
	}
	[HarmonyPatch]
	public static class PlayerPatcher
	{
		public static PlayerControllerB localPlayerController;

		public static int vanillaHotbarSize = -1;

		public static int reservedItemsStartIndex = 4;

		public static int oldHotbarSize = -1;

		private static bool isSynced = false;

		public static int INTERACTABLE_OBJECT_MASK { get; private set; }

		public static int reservedHotbarSize => SyncManager.numReservedItemSlots;

		public static int combinedHotbarSize => reservedItemsStartIndex + reservedHotbarSize;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void ResetVariables(StartOfRound __instance)
		{
			localPlayerController = null;
			vanillaHotbarSize = -1;
			ReservedItemPatcher.isReservedHotbarFocused = false;
			ReservedItemPatcher.indexUnfocusedReservedHotbar = 0;
			ReservedItemPatcher.indexFocusedReservedHotbar = -1;
			Keybinds.localPlayerController = null;
			Keybinds.focusReservedHotbarAction = null;
			Keybinds.holdingModifierKey = false;
			SyncManager.localPlayerController = null;
			isSynced = false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
		[HarmonyPostfix]
		public static void InitializePlayerController(PlayerControllerB __instance)
		{
			if (vanillaHotbarSize == -1)
			{
				vanillaHotbarSize = __instance.ItemSlots.Length;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void OnLocalPlayerConnect(PlayerControllerB __instance)
		{
			localPlayerController = __instance;
			INTERACTABLE_OBJECT_MASK = (int)Traverse.Create((object)__instance).Field("interactableObjectsMask").GetValue();
			((MonoBehaviour)__instance).StartCoroutine(UpdateHotbarSlotsAfterSpawnAnimation());
		}

		private static IEnumerator UpdateHotbarSlotsAfterSpawnAnimation()
		{
			yield return (object)new WaitForSeconds(3f);
			if (SyncManager.isSynced && !isSynced)
			{
				OnSyncedWithServer();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		public static void OnUpdate(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance != (Object)(object)localPlayerController)
			{
				return;
			}
			if (SyncManager.isSynced && !isSynced)
			{
				OnSyncedWithServer();
			}
			if (!isSynced || reservedHotbarSize <= 0 || oldHotbarSize == __instance.ItemSlots.Length)
			{
				return;
			}
			for (int i = 0; i < HUDManager.Instance.itemSlotIconFrames.Length; i++)
			{
				if (((Object)HUDManager.Instance.itemSlotIconFrames[i]).name.ToLower().StartsWith("reserveditemslot"))
				{
					reservedItemsStartIndex = i;
					oldHotbarSize = __instance.ItemSlots.Length;
					HUDPatcher.UpdateHUD();
					break;
				}
			}
		}

		private static void OnSyncedWithServer()
		{
			Plugin.Log("Finalizing sync with server.");
			isSynced = true;
			reservedItemsStartIndex = localPlayerController.ItemSlots.Length;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				val.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[val.ItemSlots.Length + reservedHotbarSize];
			}
			oldHotbarSize = localPlayerController.ItemSlots.Length;
			HUDPatcher.AddNewHotbarSlotsHud();
		}
	}
}

BepInEx/plugins/ReservedWalkieSlot.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using ReservedWalkieSlot.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedWalkieSlot")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedWalkieSlot")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c15c320f-d8fc-4f1c-be3c-f2d2ffc41edd")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedWalkieSlot
{
	public static class ConfigSettings
	{
		public static ConfigEntry<string> activateWalkieKey;

		public static ConfigEntry<bool> hideWalkieMeshShoulder;

		public static string activateWalkieDisplayName;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			activateWalkieKey = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("ReservedWalkieSlot", "ActivateWalkieKey", "<Keyboard>/x", "Activate walkie keybind.");
			hideWalkieMeshShoulder = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("ReservedWalkieSlot", "HideWalkieOnShoulder", false, "Hides the walkie mesh while on your shoulder. Only applies in scenarios where you can view your player in third person.");
			activateWalkieDisplayName = GetDisplayName(activateWalkieKey.Value);
			currentConfigEntries.Add(((ConfigEntryBase)activateWalkieKey).Definition.Key, (ConfigEntryBase)(object)activateWalkieKey);
			currentConfigEntries.Add(((ConfigEntryBase)hideWalkieMeshShoulder).Definition.Key, (ConfigEntryBase)(object)hideWalkieMeshShoulder);
			TryRemoveOldConfigSettings();
		}

		public static string GetDisplayName(string key)
		{
			key = key.Replace("<Keyboard>/", "");
			key = key.Replace("<Mouse>/", "");
			string text = key;
			text = text.Replace("leftAlt", "Alt");
			text = text.Replace("rightAlt", "Alt");
			text = text.Replace("leftCtrl", "Ctrl");
			text = text.Replace("rightCtrl", "Ctrl");
			text = text.Replace("leftShift", "Shift");
			text = text.Replace("rightShift", "Shift");
			text = text.Replace("leftButton", "LMB");
			text = text.Replace("rightButton", "RMB");
			return text.Replace("middleButton", "MMB");
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static PlayerControllerB localPlayerController;

		private static InputAction activateWalkieAction;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void InitActions()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			activateWalkieAction = new InputAction((string)null, (InputActionType)0, ConfigSettings.activateWalkieKey.Value, (string)null, (string)null, (string)null);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void OnLocalPlayerConnect(PlayerControllerB __instance)
		{
			localPlayerController = __instance;
			if (((Component)localPlayerController).gameObject.activeSelf)
			{
				SubscribeToEvents();
			}
		}

		private static void SubscribeToEvents()
		{
			if (activateWalkieAction != null)
			{
				activateWalkieAction.performed += OnPressWalkieButtonPerformed;
				activateWalkieAction.canceled += OnReleaseWalkieButtonPerformed;
				activateWalkieAction.Enable();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				SubscribeToEvents();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable(PlayerControllerB __instance)
		{
			if (activateWalkieAction != null && !((Object)(object)__instance != (Object)(object)localPlayerController))
			{
				activateWalkieAction.performed -= OnPressWalkieButtonPerformed;
				activateWalkieAction.canceled -= OnReleaseWalkieButtonPerformed;
				activateWalkieAction.Disable();
			}
		}

		private static void OnPressWalkieButtonPerformed(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject))
			{
				return;
			}
			WalkieTalkie mainWalkie = ReservedWalkieSlotPatcher.GetMainWalkie(localPlayerController);
			if (((CallbackContext)(ref context)).performed && !((Object)(object)mainWalkie == (Object)null) && ((GrabbableObject)mainWalkie).isBeingUsed)
			{
				float num = (float)Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").GetValue();
				if (!(num < 0.075f))
				{
					Plugin.Log("Talking into walkie");
					ShipBuildModeManager.Instance.CancelBuildMode(true);
					((GrabbableObject)mainWalkie).UseItemOnClient(true);
					Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").SetValue((object)0);
				}
			}
		}

		private static void OnReleaseWalkieButtonPerformed(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && localPlayerController.isPlayerControlled && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
			{
				WalkieTalkie mainWalkie = ReservedWalkieSlotPatcher.GetMainWalkie(localPlayerController);
				if (((CallbackContext)(ref context)).canceled && !((Object)(object)mainWalkie == (Object)null))
				{
					Plugin.Log("Not talking into walkie");
					ShipBuildModeManager.Instance.CancelBuildMode(true);
					((GrabbableObject)mainWalkie).UseItemOnClient(false);
				}
			}
		}
	}
	[BepInPlugin("FlipMods.ReservedWalkieSlot", "ReservedWalkieSlot", "1.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private Harmony _harmony;

		public static ReservedItemInfo walkieInfo = new ReservedItemInfo("Walkie-talkie", 100, true, true, true, true);

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("ReservedWalkieSlot");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ReservedWalkieSlot loaded");
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedWalkieSlot";

		public const string PLUGIN_NAME = "ReservedWalkieSlot";

		public const string PLUGIN_VERSION = "1.5.3";
	}
}
namespace ReservedWalkieSlot.Patches
{
	[HarmonyPatch]
	internal static class ReservedWalkieSlotPatcher
	{
		private static Vector3 localPlayerShoulderPositionOffset = new Vector3(0.125f, 0.4f, 0.125f);

		private static Vector3 playerShoulderPositionOffset = new Vector3(0.15f, -0.05f, 0.25f);

		private static Vector3 playerShoulderRotationOffset = new Vector3(0f, 270f, 100f);

		private static string originalControlTooltip = "";

		public static PlayerControllerB localPlayerController => PlayerPatcher.localPlayerController;

		public static WalkieTalkie GetMainWalkie(PlayerControllerB playerController)
		{
			return GetCurrentlySelectedWalkie(playerController) ?? GetReservedWalkie(playerController);
		}

		public static WalkieTalkie GetReservedWalkie(PlayerControllerB playerController)
		{
			return (WalkieTalkie)(SyncManager.syncReservedItemsList.Contains(Plugin.walkieInfo) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static WalkieTalkie GetCurrentlySelectedWalkie(PlayerControllerB playerController)
		{
			return (WalkieTalkie)((playerController.currentItemSlot >= 0 && playerController.currentItemSlot < playerController.ItemSlots.Length) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		[HarmonyPatch(typeof(WalkieTalkie), "__initializeVariables")]
		[HarmonyPostfix]
		public static void EditTooltips(WalkieTalkie __instance)
		{
			if (originalControlTooltip == "")
			{
				originalControlTooltip = ((GrabbableObject)__instance).itemProperties.toolTips[((GrabbableObject)__instance).itemProperties.toolTips.Length - 1];
			}
			((GrabbableObject)__instance).itemProperties.toolTips[((GrabbableObject)__instance).itemProperties.toolTips.Length - 1] = $"{originalControlTooltip}[{ConfigSettings.activateWalkieDisplayName.ToUpper()}]";
		}

		[HarmonyPatch(typeof(MenuManager), "OnEnable")]
		[HarmonyPostfix]
		public static void ResetVariables()
		{
			Keybinds.localPlayerController = null;
		}

		[HarmonyPatch(typeof(WalkieTalkie), "PocketItem")]
		[HarmonyPostfix]
		public static void OnPocketWalkie(WalkieTalkie __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController)
				{
					((Component)((Component)__instance).GetComponentInChildren<Renderer>()).gameObject.layer = 23;
				}
				else
				{
					((Component)((Component)__instance).GetComponentInChildren<Renderer>()).gameObject.layer = 6;
				}
				((GrabbableObject)__instance).parentObject = ((Component)((GrabbableObject)__instance).playerHeldBy.playerBadgeMesh).transform.parent;
			}
		}

		[HarmonyPatch(typeof(WalkieTalkie), "EquipItem")]
		[HarmonyPostfix]
		public static void OnEquipWalkie(WalkieTalkie __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				((Component)((Component)__instance).GetComponentInChildren<Renderer>()).gameObject.layer = 6;
				((GrabbableObject)__instance).parentObject = (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)localPlayerController) ? ((GrabbableObject)__instance).playerHeldBy.localItemHolder : ((GrabbableObject)__instance).playerHeldBy.serverItemHolder);
			}
		}

		[HarmonyPatch(typeof(WalkieTalkie), "DiscardItem")]
		[HarmonyPostfix]
		public static void OnDiscardWalkie(WalkieTalkie __instance)
		{
			((Component)((Component)__instance).GetComponentInChildren<Renderer>()).gameObject.layer = 6;
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void SetPositionOffset(GrabbableObject __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is WalkieTalkie && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance.parentObject != (Object)null && __instance.isPocketed && (Object)(object)__instance == (Object)(object)GetReservedWalkie(__instance.playerHeldBy) && (Object)(object)__instance != (Object)(object)GetCurrentlySelectedWalkie(__instance.playerHeldBy))
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = ((Component)__instance.parentObject).transform.rotation * Quaternion.Euler(playerShoulderRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * playerShoulderPositionOffset;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EnableItemMeshes")]
		[HarmonyPrefix]
		public static void OnEnableItemMeshes(ref bool enable, GrabbableObject __instance)
		{
			if (__instance is WalkieTalkie && (Object)(object)__instance.playerHeldBy != (Object)null && (Object)(object)__instance == (Object)(object)GetReservedWalkie(__instance.playerHeldBy) && !ConfigSettings.hideWalkieMeshShoulder.Value)
			{
				enable = true;
			}
		}
	}
}

BepInEx/plugins/Yippee.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YippeeMod.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Yippee")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds a yippee (tbh creature) as scrap.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Yippee")]
[assembly: AssemblyTitle("Yippee")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace YippeeMod
{
	[BepInPlugin("ainavt.lc.yippee", "Yippee Scrap", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static Plugin instance;

		private static ManualLogSource logSource;

		private AssetBundle assetBundle;

		private ConfigEntry<int> configRarity;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			logSource = Logger.CreateLogSource("ainavt.lc.yippee");
			LoadScrap(PathUtils.PathForResourceInAssembly("ainavt_yippee"), "Assets/mods/Yippee/Yippee.asset", "Yippee");
			logSource.LogInfo((object)"Yippee Scrap loaded!");
		}

		private void LoadScrap(string assetBundlePath, string innerAssetPath, string name)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0046: Expected O, but got Unknown
			configRarity = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition("General", name + " Rarity"), 30, new ConfigDescription("How often " + name + " will show up. Higher value means more likely to show up", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			assetBundle = AssetBundle.LoadFromFile(assetBundlePath);
			Item val = assetBundle.LoadAsset<Item>(innerAssetPath);
			if ((Object)(object)val == (Object)null)
			{
				logSource.LogError((object)("Failed to load " + name + " assets."));
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Items.RegisterScrap(val, configRarity.Value, (LevelTypes)510);
			logSource.LogInfo((object)(name + " scrap loaded!"));
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct PluginInfo
	{
		public const string Guid = "ainavt.lc.yippee";

		public const string Name = "Yippee Scrap";

		public const string Version = "1.0.0";
	}
}
namespace YippeeMod.Utils
{
	internal static class PathUtils
	{
		public static string PathForResourceInAssembly(string resourceName, Assembly? assembly = null)
		{
			Assembly assembly2 = assembly ?? Assembly.GetExecutingAssembly();
			return Path.Combine(Path.GetDirectoryName(assembly2.Location), resourceName);
		}
	}
}

BepInEx/plugins/FreeBirdTotemRemixJester.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FreeBirdTotemRemixJester.Patches;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FreeBirdTotemRemixJester")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FreeBirdTotemRemixJester")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c8e7b974-251d-4ed2-9692-91fd06040951")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FreeBirdTotemRemixJester
{
	[BepInPlugin("TopraksuK.FBTRJ", "Free Bird Totem Remix for Jester Mod", "1.0.1")]
	public class LethalBruhModBase : BaseUnityPlugin
	{
		private const string modGUID = "TopraksuK.FBTRJ";

		private const string modName = "Free Bird Totem Remix for Jester Mod";

		private const string modVersion = "1.0.1";

		private readonly Harmony harmony = new Harmony("TopraksuK.FBTRJ");

		private static LethalBruhModBase Instance;

		internal ManualLogSource MLS;

		internal static AudioClip[] windingSFX;

		internal static AudioClip[] screamSFX;

		private void Awake()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			MLS = Logger.CreateLogSource("TopraksuK.FBTRJ");
			MLS.LogInfo((object)"Loading Free Bird TOTEM Remix for Jester.");
			AssetBundle val = AssetBundle.LoadFromFile(((BaseUnityPlugin)Instance).Info.Location.TrimEnd("FreeBirdTotemRemixJester.dll".ToCharArray()) + "jestersfx");
			if ((Object)val == (Object)null || (Object)val == (Object)null)
			{
				MLS.LogError((object)"Failed to load audio asset for Jester Free Bird TOTEM Remix Theme!");
				return;
			}
			windingSFX = val.LoadAssetWithSubAssets<AudioClip>("assets/freebird1.mp3");
			screamSFX = val.LoadAssetWithSubAssets<AudioClip>("assets/freebird2.mp3");
			harmony.PatchAll(typeof(JesterAIPatch));
			MLS.LogInfo((object)"Free Bird Totem Remix for Jester Mod. Press ESC if the game is frozen occasionally.");
			harmony.PatchAll(typeof(LethalBruhModBase));
		}
	}
}
namespace FreeBirdTotemRemixJester.Patches
{
	[HarmonyPatch(typeof(JesterAI))]
	internal class JesterAIPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void JesterAIPopUpSFXPatch(ref AudioClip ___popGoesTheWeaselTheme)
		{
			AudioClip[] windingSFX = LethalBruhModBase.windingSFX;
			if (windingSFX != null && windingSFX.Length != 0)
			{
				AudioClip val = windingSFX[0];
				___popGoesTheWeaselTheme = val;
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void JesterAIScreamSFXPatch(ref AudioClip ___screamingSFX)
		{
			AudioClip[] screamSFX = LethalBruhModBase.screamSFX;
			if (screamSFX != null && screamSFX.Length != 0)
			{
				AudioClip val = screamSFX[0];
				___screamingSFX = val;
			}
		}

		[HarmonyPatch("SetJesterInitialValues")]
		[HarmonyPostfix]
		public static void JestAIInitialPatch(ref float ___popUpTimer)
		{
			___popUpTimer = 35f;
		}
	}
}

BepInEx/plugins/LethalPresents.dll

Decompiled 8 months 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 GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalPresents")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("LethalPresents mod")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("LethalPresents")]
[assembly: AssemblyTitle("LethalPresents")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalPresents
{
	[BepInPlugin("LethalPresents", "LethalPresents", "1.0.3")]
	public class LethalPresentsPlugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("LethalPresents");

		private static bool isHost;

		private static SelectableLevel currentLevel;

		public static ManualLogSource mls;

		private static int spawnChance = 5;

		private static string[] disabledEnemies = new string[0];

		private static bool IsAllowlist = false;

		private static bool ShouldSpawnMines = false;

		private static bool ShouldSpawnTurrets = false;

		private void Awake()
		{
			mls = Logger.CreateLogSource("LethalPresents");
			mls.LogInfo((object)"Plugin LethalPresents is loaded!");
			loadConfig();
			harmony.PatchAll(typeof(LethalPresentsPlugin));
		}

		private void loadConfig()
		{
			spawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 5, "Chance of spawning an enemy when opening a present [0-100]").Value;
			disabledEnemies = ((BaseUnityPlugin)this).Config.Bind<string>("General", "EnemyBlocklist", "", "Enemy blocklist separated by , and without whitespaces").Value.Split(",");
			IsAllowlist = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsAllowlist", false, "Turns blocklist into allowlist, blocklist must contain at least one inside and one outside enemy, use at your own risk").Value;
			ShouldSpawnMines = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldSpawnMines", true, "Add mines to the spawn pool [WIP]").Value;
			ShouldSpawnTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldSpawnTurrets", true, "Add turrets to the spawn pool [WIP]").Value;
		}

		[HarmonyPatch(typeof(RoundManager), "Start")]
		[HarmonyPrefix]
		private static void setIsHost()
		{
			isHost = ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost;
		}

		[HarmonyPatch(typeof(RoundManager), "AdvanceHourAndSpawnNewBatchOfEnemies")]
		[HarmonyPrefix]
		private static void updateCurrentLevelInfo(ref EnemyVent[] ___allEnemyVents, ref SelectableLevel ___currentLevel)
		{
			currentLevel = ___currentLevel;
			mls.LogInfo((object)"List of spawnable enemies (inside):");
			currentLevel.Enemies.ForEach(delegate(SpawnableEnemyWithRarity e)
			{
				mls.LogInfo((object)((Object)e.enemyType).name);
			});
			mls.LogInfo((object)"List of spawnable enemies (outside):");
			currentLevel.OutsideEnemies.ForEach(delegate(SpawnableEnemyWithRarity e)
			{
				mls.LogInfo((object)((Object)e.enemyType).name);
			});
		}

		private static void chooseAndSpawnEnemy(bool inside, Vector3 pos, Vector3 player_pos)
		{
			//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)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: 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_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource obj = mls;
			Vector3 val = player_pos;
			obj.LogInfo((object)("Player pos " + ((object)(Vector3)(ref val)).ToString()));
			List<SpawnableEnemyWithRarity> list = currentLevel.Enemies.Where((SpawnableEnemyWithRarity e) => disabledEnemies.Contains(e.enemyType.enemyName) ? IsAllowlist : (!IsAllowlist)).ToList();
			List<SpawnableEnemyWithRarity> list2 = currentLevel.OutsideEnemies.Where((SpawnableEnemyWithRarity e) => disabledEnemies.Contains(e.enemyType.enemyName) ? IsAllowlist : (!IsAllowlist)).ToList();
			int num = Random.Range(1, 2 + (list2.Count + list.Count) / 2);
			if (num == 2 && !ShouldSpawnMines)
			{
				num = 1;
			}
			if (num == 1 && !ShouldSpawnTurrets)
			{
				num = 2;
			}
			if (num == 2 && !ShouldSpawnMines)
			{
				num = 3;
			}
			switch (num)
			{
			case 1:
			{
				SpawnableMapObject[] spawnableMapObjects2 = currentLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val4 in spawnableMapObjects2)
				{
					if (!((Object)(object)val4.prefabToSpawn.GetComponentInChildren<Turret>() == (Object)null))
					{
						pos -= Vector3.up * 1.8f;
						GameObject val5 = Object.Instantiate<GameObject>(val4.prefabToSpawn, pos, Quaternion.identity);
						val5.transform.position = pos;
						Transform transform = val5.transform;
						val = player_pos - pos;
						transform.forward = ((Vector3)(ref val)).normalized;
						val5.GetComponent<NetworkObject>().Spawn(true);
						ManualLogSource obj3 = mls;
						val = pos;
						obj3.LogInfo((object)("Tried spawning a turret at " + ((object)(Vector3)(ref val)).ToString()));
						break;
					}
				}
				return;
			}
			case 2:
			{
				SpawnableMapObject[] spawnableMapObjects = currentLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val2 in spawnableMapObjects)
				{
					if (!((Object)(object)val2.prefabToSpawn.GetComponentInChildren<Landmine>() == (Object)null))
					{
						pos -= Vector3.up * 1.8f;
						GameObject val3 = Object.Instantiate<GameObject>(val2.prefabToSpawn, pos, Quaternion.identity);
						val3.transform.position = pos;
						val3.transform.forward = new Vector3(1f, 0f, 0f);
						val3.GetComponent<NetworkObject>().Spawn(true);
						ManualLogSource obj2 = mls;
						val = pos;
						obj2.LogInfo((object)("Tried spawning a mine at " + ((object)(Vector3)(ref val)).ToString()));
						break;
					}
				}
				return;
			}
			}
			SpawnableEnemyWithRarity val6;
			if (inside)
			{
				if (list.Count < 1)
				{
					mls.LogInfo((object)"Cant spawn enemy - no other enemies present to copy from");
					return;
				}
				val6 = list[Random.Range(0, list.Count - 1)];
			}
			else
			{
				if (list2.Count < 1)
				{
					mls.LogInfo((object)"Cant spawn enemy - no other enemies present to copy from");
					return;
				}
				val6 = list2[Random.Range(0, list2.Count - 1)];
			}
			pos += Vector3.up * 0.25f;
			ManualLogSource obj4 = mls;
			string enemyName = val6.enemyType.enemyName;
			val = pos;
			obj4.LogInfo((object)("Spawning " + enemyName + " at " + ((object)(Vector3)(ref val)).ToString()));
			SpawnEnemy(val6, pos, 0f);
		}

		[HarmonyPatch(typeof(GiftBoxItem), "OpenGiftBoxServerRpc")]
		[HarmonyPrefix]
		private static void spawnRandomEntity(GiftBoxItem __instance)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			int value = Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue<int>();
			mls.LogInfo((object)("IsServer:" + networkManager.IsServer + " IsHost:" + networkManager.IsHost + " __rpc_exec_stage:" + value));
			if (value == 1 && isHost)
			{
				int num = Random.Range(1, 100);
				mls.LogInfo((object)("Player's fortune:" + num));
				if (num < spawnChance)
				{
					chooseAndSpawnEnemy(((GrabbableObject)__instance).isInFactory, ((Component)__instance).transform.position, ((Component)Traverse.Create((object)__instance).Field("previousPlayerHeldBy").GetValue<PlayerControllerB>()).transform.position);
				}
			}
		}

		private static void SpawnEnemy(SpawnableEnemyWithRarity enemy, Vector3 pos, float rot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			RoundManager.Instance.SpawnEnemyGameObject(pos, rot, -1, enemy.enemyType);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalPresents";

		public const string PLUGIN_NAME = "LethalPresents";

		public const string PLUGIN_VERSION = "1.0.3";
	}
}

BepInEx/plugins/Ryokune.CompatibilityChecker.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using CompatibilityChecker.MonoBehaviours;
using CompatibilityChecker.Netcode;
using CompatibilityChecker.Patches;
using CompatibilityChecker.Utils;
using HarmonyLib;
using Newtonsoft.Json;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Ryokune")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Lethal Company Library that lets you know which mods a modded server has.")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyInformationalVersion("1.1.6")]
[assembly: AssemblyProduct("CompatibilityChecker")]
[assembly: AssemblyTitle("Ryokune.CompatibilityChecker")]
[assembly: AssemblyVersion("1.1.6.0")]
namespace CompatibilityChecker
{
	[BepInPlugin("Ryokune.CompatibilityChecker", "CompatibilityChecker", "1.1.6")]
	[BepInProcess("Lethal Company.exe")]
	public class ModNotifyBase : BaseUnityPlugin
	{
		public static ModNotifyBase instance;

		public static ManualLogSource Logger;

		private readonly Harmony harmony = new Harmony("Ryokune.CompatibilityChecker");

		public static Dictionary<string, PluginInfo> ModList = new Dictionary<string, PluginInfo>();

		public static string ModListString;

		public static string[] ModListArray;

		public static bool loadedMods;

		public static string seperator = "/@/";

		public static string Text;

		public static TMP_InputField searchInputField;

		private static IEnumerator JoinLobby(SteamId lobbyId, SteamLobbyManager lobbyManager)
		{
			//IL_0007: 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)
			bool found = false;
			Logger.LogWarning((object)"Getting Lobby");
			Task<Lobby?> joinTask = SteamMatchmaking.JoinLobbyAsync(lobbyId);
			yield return (object)new WaitUntil((Func<bool>)(() => joinTask.IsCompleted));
			if (joinTask.Result.HasValue)
			{
				Logger.LogWarning((object)"Getting Lobby Value");
				Lobby lobby = joinTask.Result.Value;
				if (!Utility.IsNullOrWhiteSpace(((Lobby)(ref lobby)).GetData("vers")))
				{
					LobbySlot.JoinLobbyAfterVerifying(lobby, ((Lobby)(ref lobby)).Id);
					found = true;
					Logger.LogWarning((object)"Success!");
				}
				lobby = default(Lobby);
			}
			else
			{
				Logger.LogWarning((object)"Failed to join lobby.");
			}
			if (!found)
			{
				lobbyManager.LoadServerList();
			}
			else if ((Object)(object)searchInputField != (Object)null)
			{
				searchInputField.text = "";
				Text = "";
			}
		}

		private static void OnEndEdit(string newValue)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Text = newValue;
			SteamLobbyManager val = Object.FindObjectOfType<SteamLobbyManager>();
			if (ulong.TryParse(newValue, out var result))
			{
				SteamId val2 = default(SteamId);
				val2.Value = result;
				CoroutineHandler.Instance.NewCoroutine(JoinLobby(SteamId.op_Implicit(result), val));
			}
			else
			{
				val.LoadServerList();
			}
		}

		private static IEnumerator displayCopied(TextMeshProUGUI textMesh)
		{
			string oldtext = ((TMP_Text)textMesh).text;
			if (GameNetworkManager.Instance.currentLobby.HasValue)
			{
				((TMP_Text)textMesh).text = "(Copied to clipboard!)";
				Lobby value = GameNetworkManager.Instance.currentLobby.Value;
				SteamId id2 = ((Lobby)(ref value)).Id;
				string id = (GUIUtility.systemCopyBuffer = ((object)(SteamId)(ref id2)).ToString());
				Logger.LogWarning((object)("Lobby code copied to clipboard: " + id));
			}
			else
			{
				((TMP_Text)textMesh).text = "Can't get Lobby code!";
			}
			yield return (object)new WaitForSeconds(1.2f);
			((TMP_Text)textMesh).text = oldtext;
		}

		private static void sceneLoad(Scene sceneName, LoadSceneMode load)
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			if (((Scene)(ref sceneName)).name == "MainMenu")
			{
				GameObject val = GameObject.Find("/Canvas/MenuContainer/LobbyList/JoinCode");
				if ((Object)(object)val != (Object)null)
				{
					try
					{
						GameObject val2 = Object.Instantiate<GameObject>(val.gameObject, val.transform.parent);
						val2.SetActive(true);
						searchInputField = val2.GetComponent<TMP_InputField>();
						((Selectable)searchInputField).interactable = true;
						((TMP_Text)((Component)searchInputField.placeholder).gameObject.GetComponent<TextMeshProUGUI>()).text = "Search or Enter a room code...";
						searchInputField.onEndEdit = new SubmitEvent();
						searchInputField.onEndTextSelection = new TextSelectionEvent();
						searchInputField.onSubmit = new SubmitEvent();
						((UnityEvent<string>)(object)searchInputField.onSubmit).AddListener((UnityAction<string>)OnEndEdit);
					}
					catch (Exception ex)
					{
						Logger.LogError((object)ex);
					}
				}
			}
			else
			{
				if (!(((Scene)(ref sceneName)).name == "SampleSceneRelay"))
				{
					return;
				}
				GameObject val3 = GameObject.Find("/Systems/UI/Canvas/QuickMenu/MainButtons/Resume");
				if ((Object)(object)val3 != (Object)null)
				{
					GameObject val4 = Object.Instantiate<GameObject>(val3.gameObject, val3.transform.parent);
					RectTransform component = val4.GetComponent<RectTransform>();
					component.anchoredPosition += new Vector2(0f, 182f);
					TextMeshProUGUI LobbyCodeTextMesh = val4.GetComponentInChildren<TextMeshProUGUI>();
					((TMP_Text)LobbyCodeTextMesh).text = "> Lobby Code";
					Button component2 = val4.GetComponent<Button>();
					component2.onClick = new ButtonClickedEvent();
					((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
					{
						CoroutineHandler.Instance.NewCoroutine(displayCopied(LobbyCodeTextMesh));
					});
				}
			}
		}

		private void Awake()
		{
			SceneManager.sceneLoaded += sceneLoad;
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
				Logger = ((BaseUnityPlugin)this).Logger;
			}
			CoroutineHandler.Instance.NewCoroutine(ThunderstoreAPI.Initialize());
			Logger.LogInfo((object)"Plugin Ryokune.CompatibilityChecker is loaded!");
			Logger.LogInfo((object)"Modded servers with CompatibilityChecker will now notify you what mods are needed.");
			harmony.PatchAll(typeof(ModNotifyBase));
			harmony.PatchAll(typeof(PlayerJoinNetcode));
			harmony.PatchAll(typeof(SteamLobbyManagerPatch));
		}

		public static IEnumerator InitializeModsCoroutine()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => ThunderstoreAPI.Packages != null));
			ModList = Chainloader.PluginInfos;
			StringBuilder messageBuilder = new StringBuilder();
			MenuManager menuManager = Object.FindObjectOfType<MenuManager>();
			PlayerJoinNetcode.old = ((((Component)((TMP_Text)menuManager.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta != Vector2.zero) ? ((Component)((TMP_Text)menuManager.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta : PlayerJoinNetcode.old);
			int i = 0;
			int count = ModList.Count();
			menuManager.menuNotification.SetActive(true);
			foreach (PluginInfo info in ModList.Values)
			{
				i++;
				((TMP_Text)menuManager.menuNotificationText).text = $"Loading mods {i}/{count}";
				((TMP_Text)menuManager.menuNotificationButtonText).text = null;
				((Component)((TMP_Text)menuManager.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta = Vector2.zero;
				string noSpace = Regex.Replace(info.Metadata.Name, "[\\s\\-_]", "");
				Package package = ThunderstoreAPI.GetPackage(noSpace, info);
				if (package != null)
				{
					Logger.LogInfo((object)$"[{info.Metadata.GUID}] Found package: {info.Metadata.Name}[{info.Metadata.Version}]\n\t\tDATA:\n\t\t--NAME: {package.FullName}\n\t\t--LINK: {package.PackageUrl}");
					if (VersionUtil.ConvertToNumber(package.Versions[0].VersionNumber) > VersionUtil.ConvertToNumber(info.Metadata.Version.ToString()))
					{
						messageBuilder.AppendLine($"\n\t\t--Mod {info.Metadata.Name} [{info.Metadata.GUID}] v{info.Metadata.Version} does not equal the latest release!");
						messageBuilder.AppendLine("\t\t--Latest version: v" + package.Versions[0].VersionNumber);
						messageBuilder.AppendLine("\t\t--Link: " + package.PackageUrl);
						messageBuilder.AppendLine("\t\t--Full mod name: " + package.FullName);
						messageBuilder.AppendLine("\t\t--(If this is wrong, please ignore this.)");
					}
				}
				if (package?.Categories.Contains("Server-side") ?? false)
				{
					if (package.Name == "CompatibilityChecker" && package.Versions[0].VersionNumber != "1.1.6")
					{
						string warning = "Current CompatibilityChecker v1.1.6 does not equal latest release v" + package.Versions[0].VersionNumber + "!\nPlease update to the latest version of CompatibilityChecker!!!";
						Logger.LogWarning((object)warning);
						Object.FindObjectOfType<MenuManager>().DisplayMenuNotification(warning, (string)null);
					}
					ModListString += $"{info.Metadata.Name}[{info.Metadata.Version}]{seperator}";
				}
				else if (package == null)
				{
					Logger.LogWarning((object)$"Couldn't find package: {info.Metadata.Name}[{info.Metadata.Version}]\n\t\t[{info.Metadata.GUID}]");
					ModListString += $"{info.Metadata.GUID}[{info.Metadata.Version}]{seperator}";
				}
				yield return null;
			}
			if (messageBuilder.Length != 0)
			{
				Logger.LogWarning((object)messageBuilder.ToString());
			}
			ModListString = ModListString.Remove(ModListString.Length - 3, 3);
			ModListArray = ModListString.Split(seperator);
			Logger.LogWarning((object)$"Server-sided Mod List Count: {ModListArray.Count()}");
			menuManager.menuNotification.SetActive(false);
			loadedMods = true;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Ryokune.CompatibilityChecker";

		public const string PLUGIN_NAME = "CompatibilityChecker";

		public const string PLUGIN_VERSION = "1.1.6";
	}
}
namespace CompatibilityChecker.Utils
{
	[Serializable]
	public class Package
	{
		[JsonProperty("name")]
		public string Name;

		[JsonProperty("full_name")]
		public string FullName;

		[JsonProperty("owner")]
		public string Owner;

		[JsonProperty("package_url")]
		public string PackageUrl;

		[JsonProperty("categories")]
		public string[] Categories;

		[JsonProperty("versions")]
		public Version[] Versions;

		public long TotalDownloads;

		[JsonProperty("is_deprecated")]
		public bool IsDeprecated;
	}
	[Serializable]
	public class Version
	{
		[JsonProperty("name")]
		public string Name;

		[JsonProperty("full_name")]
		public string FullName;

		[JsonProperty("version_number")]
		public string VersionNumber;

		[JsonProperty("download_url")]
		public Uri DownloadUrl;

		[JsonProperty("downloads")]
		public long Downloads;

		[JsonProperty("website_url")]
		public Uri WebsiteUrl;
	}
	public static class ThunderstoreAPI
	{
		private const string ApiBaseUrl = "https://thunderstore.io/c/lethal-company/api/v1/package/";

		private static List<Package> packages;

		public static List<Package> Packages => packages;

		public static async Task InitializeThunderstorePackagesAsync(Action onComplete)
		{
			try
			{
				using HttpClient httpClient = new HttpClient();
				packages = JsonConvert.DeserializeObject<List<Package>>(await httpClient.GetStringAsync("https://thunderstore.io/c/lethal-company/api/v1/package/"));
				ModNotifyBase.Logger.LogInfo((object)$"ThunderstoreAPI Initialized! Got packages: {packages.Count()}");
				foreach (Package pack in packages)
				{
					Version[] versions = pack.Versions;
					foreach (Version ver in versions)
					{
						pack.TotalDownloads += ver.Downloads;
					}
				}
			}
			catch (Exception ex2)
			{
				Exception ex = ex2;
				ModNotifyBase.Logger.LogError((object)("Failed to initialize Thunderstore packages. Error: " + ex.Message));
			}
			onComplete?.Invoke();
		}

		public static bool IsSimilar(string s1, string s2)
		{
			string pattern = string.Join(".*?", s2.ToCharArray());
			Match match = Regex.Match(s1, pattern);
			if (match.Success)
			{
				return match.Success;
			}
			int[,] array = new int[s1.Length + 1, s2.Length + 1];
			for (int i = 0; i <= s1.Length; i++)
			{
				for (int j = 0; j <= s2.Length; j++)
				{
					if (i == 0)
					{
						array[i, j] = j;
					}
					else if (j == 0)
					{
						array[i, j] = i;
					}
					else
					{
						array[i, j] = Math.Min(Math.Min(array[i - 1, j] + 1, array[i, j - 1] + 1), array[i - 1, j - 1] + ((s1[i - 1] != s2[j - 1]) ? 1 : 0));
					}
				}
			}
			int num = Math.Max(s1.Length, s2.Length);
			int num2 = array[s1.Length, s2.Length];
			double num3 = 1.0 - (double)num2 / (double)num;
			return num3 > 0.54;
		}

		private static bool IsMatchingName(Package package, string searchString)
		{
			string[] array = Regex.Split(package.Name, "(?<=[a-z])(?=[A-Z])|[\\s_\\-]");
			string[] searchStringSplit = Regex.Split(searchString, "(?<=[a-z])(?=[A-Z])|[\\s_\\-]");
			int num = ((array.Length > searchStringSplit.Length) ? (searchStringSplit.Length / 2) : (array.Length / 2));
			int num2 = array.Count((string token) => searchStringSplit.Contains<string>(token, StringComparer.OrdinalIgnoreCase));
			return num2 >= num;
		}

		private static bool IsMatchingName(Package package, string searchString, string owner)
		{
			string[] source = Regex.Split(Regex.Replace(package.Name, "[\\s_]+(\\w)", (Match m) => m.Groups[1].Value.ToUpper()).Replace(" ", ""), "(?<=[a-z])(?=[A-Z])");
			string[] searchStringNameTokens = Regex.Split(searchString, "(?<=[a-z])(?=[A-Z])");
			int num = 2;
			int num2 = source.Count((string token) => searchStringNameTokens.Contains<string>(token, StringComparer.OrdinalIgnoreCase));
			return num2 >= num && owner.Contains(package.Owner, StringComparison.OrdinalIgnoreCase);
		}

		public static List<Package> GetPackages(string searchString)
		{
			return Packages?.Where((Package package) => IsMatchingName(package, searchString)).ToList();
		}

		public static List<Package> GetPackages(string searchString, string owner)
		{
			return Packages?.Where((Package package) => IsMatchingName(package, searchString, owner)).ToList();
		}

		public static Package GetPackage(string searchString)
		{
			Package package = null;
			foreach (Package package2 in Packages)
			{
				if (package2.IsDeprecated)
				{
					continue;
				}
				string text = Regex.Replace(package2.Name, "[\\s\\-_]", "");
				if (text.Equals(searchString, StringComparison.OrdinalIgnoreCase) || searchString.Contains(text, StringComparison.OrdinalIgnoreCase) || text.Contains(searchString, StringComparison.OrdinalIgnoreCase))
				{
					if (package == null)
					{
						package = package2;
					}
					if (package2.TotalDownloads >= package?.TotalDownloads)
					{
						package = package2;
					}
				}
			}
			return package;
		}

		public static Package GetPackage(string searchString, PluginInfo info)
		{
			Package result = null;
			bool flag = false;
			foreach (Package package in Packages)
			{
				if (package.IsDeprecated)
				{
					continue;
				}
				if (info.Metadata.GUID.Split(".").Contains(package.Owner))
				{
					flag = true;
				}
				string text = Regex.Replace(package.Name, "[\\s\\-_]", "");
				if (text.Equals(searchString, StringComparison.OrdinalIgnoreCase) || text.Equals(info.Metadata.Name, StringComparison.OrdinalIgnoreCase) || text.Equals(info.Metadata.GUID, StringComparison.OrdinalIgnoreCase))
				{
					if (flag)
					{
						return package;
					}
					result = package;
				}
				if (searchString.Contains(text, StringComparison.OrdinalIgnoreCase) || text.Contains(searchString, StringComparison.OrdinalIgnoreCase) || text.Contains(info.Metadata.Name, StringComparison.OrdinalIgnoreCase) || text.Contains(info.Metadata.GUID, StringComparison.OrdinalIgnoreCase))
				{
					result = package;
				}
				if (IsSimilar(package.Name, searchString))
				{
					result = package;
				}
			}
			return result;
		}

		public static IEnumerator Initialize(Action onComplete = null)
		{
			yield return InitializeThunderstorePackagesAsync(onComplete);
		}
	}
	internal static class VersionUtil
	{
		public static int ConvertToNumber(string version)
		{
			string s = version.Replace(".", "");
			if (int.TryParse(s, out var result))
			{
				return result;
			}
			ModNotifyBase.Logger.LogError((object)("Error parsing version: " + version));
			return 0;
		}
	}
}
namespace CompatibilityChecker.Patches
{
	internal class SteamLobbyManagerPatch
	{
		[HarmonyPatch(typeof(SteamLobbyManager), "LoadServerList")]
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "me.swipez.melonloader.morecompany" })]
		public static void loadserverListPatch(ref SteamLobbyManager __instance, ref Lobby[] ___currentLobbyList)
		{
			CoroutineHandler.Instance.NewCoroutine(BetterCompatibility(__instance));
		}

		public static IEnumerator BetterCompatibility(SteamLobbyManager lobbyManager)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => ((Transform)((Component)lobbyManager.levelListContainer).GetComponent<RectTransform>()).childCount - 1 != 0 && ((Transform)((Component)lobbyManager.levelListContainer).GetComponent<RectTransform>()).childCount - 1 == Object.FindObjectsOfType(typeof(LobbySlot)).Length && !GameNetworkManager.Instance.waitingForLobbyDataRefresh));
			int i = 0;
			float lobbySlotPositionOffset = 0f;
			try
			{
				LobbySlot[] array = (LobbySlot[])(object)Object.FindObjectsOfType(typeof(LobbySlot));
				foreach (LobbySlot slot in array)
				{
					i++;
					Transform obj = ((Component)slot).transform.Find("JoinButton");
					GameObject JoinButton = ((obj != null) ? ((Component)obj).gameObject : null);
					if ((Object)(object)JoinButton != (Object)null)
					{
						GameObject CopyCodeButton = Object.Instantiate<GameObject>(JoinButton, JoinButton.transform.parent);
						CopyCodeButton.SetActive(true);
						RectTransform rectTransform = CopyCodeButton.GetComponent<RectTransform>();
						if ((Object)(object)rectTransform != (Object)null)
						{
							rectTransform.anchoredPosition -= new Vector2(78f, 0f);
							((TMP_Text)CopyCodeButton.GetComponentInChildren<TextMeshProUGUI>()).text = "Code";
							Button ButtonComponent = CopyCodeButton.GetComponent<Button>();
							if ((Object)(object)ButtonComponent != (Object)null)
							{
								ButtonComponent.onClick = new ButtonClickedEvent();
								((UnityEvent)ButtonComponent.onClick).AddListener((UnityAction)delegate
								{
									string text2 = (GUIUtility.systemCopyBuffer = ((object)(SteamId)(ref slot.lobbyId)).ToString());
									ModNotifyBase.Logger.LogInfo((object)("Lobby code copied to clipboard: " + text2));
								});
							}
						}
					}
					Lobby lobby = slot.thisLobby;
					if (!Utility.IsNullOrWhiteSpace(((Lobby)(ref lobby)).GetData("mods")) && !((TMP_Text)slot.LobbyName).text.Contains("[Checker]"))
					{
						((TMP_Text)slot.LobbyName).text = ((TMP_Text)slot.LobbyName).text + " [Checker]";
					}
					if (!Utility.IsNullOrWhiteSpace(ModNotifyBase.Text) && !((TMP_Text)slot.LobbyName).text.Contains(ModNotifyBase.Text, StringComparison.OrdinalIgnoreCase))
					{
						i--;
						Object.DestroyImmediate((Object)(object)((Component)slot).gameObject);
					}
					else
					{
						((Component)slot).gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, lobbySlotPositionOffset);
						lobbySlotPositionOffset -= 42f;
						lobby = default(Lobby);
					}
				}
				RectTransform rect = ((Component)lobbyManager.levelListContainer).GetComponent<RectTransform>();
				float newWidth = rect.sizeDelta.x;
				float newHeight = Mathf.Max(0f, (float)i * 42f);
				rect.SetSizeWithCurrentAnchors((Axis)0, newWidth);
				rect.SetSizeWithCurrentAnchors((Axis)1, newHeight);
			}
			catch (Exception err)
			{
				ModNotifyBase.Logger.LogError((object)err);
			}
		}

		[HarmonyPatch(typeof(SteamLobbyManager), "loadLobbyListAndFilter")]
		[HarmonyAfter(new string[] { "me.swipez.melonloader.morecompany" })]
		[HarmonyPrefix]
		public static bool loadLobbyPrefixPatch(ref SteamLobbyManager __instance, ref Lobby[] ___currentLobbyList, ref float ___lobbySlotPositionOffset, ref IEnumerator __result)
		{
			__result = modifiedLoadLobbyIEnumerator(__instance, ___currentLobbyList, ___lobbySlotPositionOffset);
			return false;
		}

		public static IEnumerator modifiedLoadLobbyIEnumerator(SteamLobbyManager __instance, Lobby[] ___currentLobbyList, float ___lobbySlotPositionOffset)
		{
			string[] offensiveWords = new string[21]
			{
				"nigger", "faggot", "n1g", "nigers", "cunt", "pussies", "pussy", "minors", "chink", "buttrape",
				"molest", "rape", "coon", "negro", "beastiality", "cocks", "cumshot", "ejaculate", "pedophile", "furfag",
				"necrophilia"
			};
			for (int i = 0; i < ___currentLobbyList.Length; i++)
			{
				Lobby currentLobby = ___currentLobbyList[i];
				Friend[] blockedUsers = SteamFriends.GetBlocked().ToArray();
				if (blockedUsers != null)
				{
					Friend[] array = blockedUsers;
					for (int j = 0; j < array.Length; j++)
					{
						Friend blockedUser = array[j];
						if (((Lobby)(ref currentLobby)).IsOwnedBy(blockedUser.Id))
						{
						}
					}
				}
				string lobbyName = ((Lobby)(ref currentLobby)).GetData("name");
				bool lobbyModded = !Utility.IsNullOrWhiteSpace(((Lobby)(ref currentLobby)).GetData("mods"));
				if (!Utility.IsNullOrWhiteSpace(lobbyName))
				{
					string lobbyNameLowercase = lobbyName.ToLower();
					if (__instance.censorOffensiveLobbyNames)
					{
						string[] array2 = offensiveWords;
						foreach (string word in array2)
						{
							if (lobbyNameLowercase.Contains(word))
							{
							}
						}
					}
					GameObject gameObject = Object.Instantiate<GameObject>(__instance.LobbySlotPrefab, __instance.levelListContainer);
					gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, ___lobbySlotPositionOffset);
					___lobbySlotPositionOffset -= 42f;
					LobbySlot componentInChildren = gameObject.GetComponentInChildren<LobbySlot>();
					((TMP_Text)componentInChildren.LobbyName).text = lobbyName + " " + (lobbyModded ? "[Checker]" : "");
					((TMP_Text)componentInChildren.playerCount).text = $"{((Lobby)(ref currentLobby)).MemberCount} / 4";
					componentInChildren.lobbyId = ((Lobby)(ref currentLobby)).Id;
					componentInChildren.thisLobby = currentLobby;
				}
				currentLobby = default(Lobby);
			}
			yield break;
		}
	}
}
namespace CompatibilityChecker.Netcode
{
	[HarmonyPatch]
	internal class PlayerJoinNetcode
	{
		private static string[] serverModList = null;

		public static Vector2 old = Vector2.zero;

		public static IEnumerator SetLobbyData(Lobby lobby)
		{
			//IL_0007: 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)
			if (GameNetworkManager.Instance.currentLobby.HasValue)
			{
				((Lobby)(ref lobby)).SetData("mods", ModNotifyBase.ModListString);
				ModNotifyBase.Logger.LogInfo((object)("Set " + ((Lobby)(ref lobby)).GetData("name") + " mods to: " + ModNotifyBase.ModListString));
			}
			yield break;
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated")]
		[HarmonyPrefix]
		public static bool OnLobbyCreated(ref GameNetworkManager __instance, Result result, ref Lobby lobby)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if ((int)result == 1)
			{
				CoroutineHandler.Instance.NewCoroutine(SetLobbyData(lobby));
			}
			return true;
		}

		[HarmonyPatch(typeof(GameNetworkManager), "StartHost")]
		[HarmonyPrefix]
		public static bool StartHost(ref GameNetworkManager __instance)
		{
			if (!ModNotifyBase.loadedMods)
			{
				CoroutineHandler.Instance.NewCoroutine(Connect());
				CoroutineHandler.Instance.NewCoroutine(ModNotifyBase.InitializeModsCoroutine());
				return false;
			}
			return true;
		}

		public static IEnumerator Connect()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => ModNotifyBase.loadedMods));
			GameNetworkManager.Instance.StartHost();
		}

		[HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")]
		[HarmonyPrefix]
		public static bool IsJoinable(ref Lobby lobby)
		{
			string data = ((Lobby)(ref lobby)).GetData("mods");
			if (!Utility.IsNullOrWhiteSpace(data))
			{
				serverModList = data.Split(ModNotifyBase.seperator);
				ModNotifyBase.Logger.LogWarning((object)(((Lobby)(ref lobby)).GetData("name") + " returned:"));
				try
				{
					string[] array = serverModList;
					foreach (string input in array)
					{
						string text = Regex.Replace(input, "\\[([\\d.]+)\\]", "");
						string text2 = (Regex.Match(input, "\\[([\\d.]+)\\]").Groups[1].Value ?? "") ?? "No version number found";
						string text3 = "";
						if (Chainloader.PluginInfos.ContainsKey(text))
						{
							PluginInfo obj = Chainloader.PluginInfos[text];
							object obj2;
							if (obj == null)
							{
								obj2 = null;
							}
							else
							{
								BepInPlugin metadata = obj.Metadata;
								obj2 = ((metadata == null) ? null : metadata.Version?.ToString());
							}
							text3 = (string)obj2;
						}
						string text4 = text;
						string text5 = ((!Utility.IsNullOrWhiteSpace(text3) && !Utility.IsNullOrWhiteSpace(text2) && !VersionUtil.ConvertToNumber(text2).Equals(VersionUtil.ConvertToNumber(text3))) ? (" (May be incompatible with your version v" + text3 + ")") : "");
						Package package = ThunderstoreAPI.GetPackage(text);
						if (package != null)
						{
							text4 = Regex.Replace(input, "\\[([\\d.]+)\\]", "") + " v" + text2 + text5;
						}
						ModNotifyBase.Logger.LogWarning((object)text4);
					}
				}
				catch (Exception ex)
				{
					ModNotifyBase.Logger.LogError((object)ex);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		[HarmonyPostfix]
		public static void JoinLobbyPostfix()
		{
			if (ModNotifyBase.ModList.Count == 0)
			{
				CoroutineHandler.Instance.NewCoroutine(ModNotifyBase.InitializeModsCoroutine());
			}
		}

		[HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")]
		[HarmonyPostfix]
		public static void SetLoadingScreenPatch(ref MenuManager __instance, ref RoomEnter result, ref bool isLoading, ref string overrideMessage)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			if (old == Vector2.zero)
			{
				old = ((Component)((TMP_Text)__instance.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta;
			}
			if ((int)result != 5 || !Utility.IsNullOrWhiteSpace(overrideMessage))
			{
				((Component)((TMP_Text)__instance.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta = old;
				return;
			}
			((Component)((TMP_Text)__instance.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta = old;
			Package package = ThunderstoreAPI.GetPackage("CompatibilityChecker");
			bool flag = VersionUtil.ConvertToNumber(package.Versions[0].VersionNumber) > VersionUtil.ConvertToNumber("1.1.6");
			string text = (flag ? ("New CompatibilityChecker update is available! v" + package.Versions[0].VersionNumber + " != 1.1.6") : "[ Close ]");
			if (flag & !isLoading)
			{
				((Component)((TMP_Text)__instance.menuNotificationButtonText).transform.parent).GetComponent<RectTransform>().sizeDelta = new Vector2(256.375f, 58.244f);
			}
			if (ModNotifyBase.ModList.Count == 0)
			{
				CoroutineHandler.Instance.NewCoroutine(ModNotifyBase.InitializeModsCoroutine());
			}
			if (Utility.IsNullOrWhiteSpace(overrideMessage) && Utility.IsNullOrWhiteSpace(GameNetworkManager.Instance.disconnectionReasonMessage) && !isLoading)
			{
				if (serverModList == null)
				{
					__instance.DisplayMenuNotification("Failed to join Modded Crew!\n Missing mods:\nCan't display: Host does not have CompatibilityChecker!", text);
				}
				else
				{
					GameNetworkManager instance = GameNetworkManager.Instance;
					object obj;
					if (instance == null)
					{
						obj = null;
					}
					else
					{
						Lobby value = instance.currentLobby.Value;
						obj = ((Lobby)(ref value)).GetData("name");
					}
					string text2 = (string)obj;
					string[] array = serverModList.Except(ModNotifyBase.ModListArray).ToArray();
					string[] array2 = ModNotifyBase.ModListArray.Except(serverModList).ToArray();
					string text3 = ((array == null || array.Length == 0) ? "None..?" : string.Join("\n", array));
					string text4 = ((array2 == null || array2.Length == 0) ? "None." : string.Join("\n\t\t", array2));
					__instance.DisplayMenuNotification("Modded crew\n(Check logs/console for links)!\n Missing mods:\n" + text3, text);
					ModNotifyBase.Logger.LogError((object)("\nMissing server-sided mods from lobby \"" + text2 + "\":"));
					string[] array3 = array;
					foreach (string text5 in array3)
					{
						string text6 = text5;
						Package package2 = ThunderstoreAPI.GetPackage(text5);
						if (package2 != null)
						{
							string text7 = (Regex.Match(text5, "\\[([\\d.]+)\\]").Success ? ("v" + Regex.Match(text5, "\\[([\\d.]+)\\]").Value) : "No version number found");
							text6 = string.Format("\n\t--Name: {0}\n\t--Link: {1}\n\t--Version: {2}\n\t--Downloads: {3}\n\t--Categories: [{4}]", text5, package2.PackageUrl, text7, package2.Versions[0].Downloads, string.Join(", ", package2.Categories));
						}
						ModNotifyBase.Logger.LogError((object)text6);
					}
					ModNotifyBase.Logger.LogWarning((object)("Mods \"" + text2 + "\" may not be compatible with:\n\t\t" + text4));
					serverModList = null;
				}
			}
			if (flag)
			{
				ModNotifyBase.Logger.LogWarning((object)("NEW VERSION OF COMPATIBILITY CHECKER IS AVAILABE. PLEASE UPDATE TO " + package.Versions[0].VersionNumber));
			}
		}

		[HarmonyPatch(typeof(MenuManager), "connectionTimeOut")]
		[HarmonyPostfix]
		public static void timeoutPatch()
		{
			//IL_0032: 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)
			if (GameNetworkManager.Instance.currentLobby.HasValue && serverModList == null)
			{
				Lobby value = GameNetworkManager.Instance.currentLobby.Value;
				serverModList = ((Lobby)(ref value)).GetData("mods")?.Split(ModNotifyBase.seperator);
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientConnectedCallback")]
		[HarmonyPostfix]
		public static void ConnectCallbackPatch()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Lobby? currentLobby = GameNetworkManager.Instance.currentLobby;
			if ((Object)(object)StartOfRound.Instance != (Object)null && currentLobby.HasValue)
			{
				Lobby value = currentLobby.Value;
				if (Utility.IsNullOrWhiteSpace(((Lobby)(ref value)).GetData("mods")))
				{
					ModNotifyBase.Logger.LogInfo((object)"Setting lobbys mods");
					CoroutineHandler.Instance.NewCoroutine(SetLobbyData(currentLobby.Value));
				}
			}
		}
	}
}
namespace CompatibilityChecker.MonoBehaviours
{
	internal class CoroutineHandler : MonoBehaviour
	{
		private static CoroutineHandler instance;

		private List<Type> runningCoroutines = new List<Type>();

		public static CoroutineHandler Instance
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)instance == (Object)null)
				{
					GameObject val = new GameObject("CoroutineHandler");
					instance = val.AddComponent<CoroutineHandler>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return instance;
			}
		}

		public void NewCoroutine(IEnumerator coroutine)
		{
			if (!IsCoroutineRunning(coroutine.GetType()))
			{
				runningCoroutines.Add(coroutine.GetType());
				((MonoBehaviour)this).StartCoroutine(ExecuteCoroutine(coroutine));
			}
			else
			{
				ModNotifyBase.Logger.LogWarning((object)("Coroutine " + coroutine.GetType().FullName + " is already running"));
			}
		}

		private bool IsCoroutineRunning(Type coroutine)
		{
			return runningCoroutines.Any((Type runningCoroutine) => runningCoroutine == coroutine);
		}

		private IEnumerator ExecuteCoroutine(IEnumerator coroutine)
		{
			yield return ((MonoBehaviour)this).StartCoroutine(coroutine);
			runningCoroutines.Remove(coroutine.GetType());
		}
	}
	public class SearchBox : MonoBehaviour
	{
		private TMP_InputField searchInputField;

		private GameObject canvas;

		public string Text = "";

		public void Awake()
		{
			ModNotifyBase.Logger.LogInfo((object)"SearchBox: I have awoken");
		}

		public void Start()
		{
			ModNotifyBase.Logger.LogInfo((object)"SearchBox: Start method called");
			LoadCanvas();
		}

		private void LoadCanvas()
		{
			canvas = GameObject.Find("/Canvas/MenuContainer/LobbyList");
			if ((Object)(object)canvas == (Object)null)
			{
				ModNotifyBase.Logger.LogError((object)"SearchBox: Canvas not found. Make sure the hierarchy and names are correct.");
				return;
			}
			ModNotifyBase.Logger.LogInfo((object)"SearchBox: Canvas found. Creating search box.");
			CreateSearchBox();
		}

		private void CreateSearchBox()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			ModNotifyBase.Logger.LogInfo((object)"SearchBox: Creating search box");
			searchInputField = CreateInputField("Search..", Vector2.zero);
			((UnityEvent<string>)(object)searchInputField.onEndEdit).AddListener((UnityAction<string>)OnEndEdit);
			RectTransform component = ((Component)searchInputField).GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(200f, 30f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.anchoredPosition = new Vector2(canvas.GetComponent<RectTransform>().sizeDelta.x / 2f, canvas.GetComponent<RectTransform>().sizeDelta.y / 2f);
			((Component)searchInputField).transform.SetParent(canvas.transform, false);
			((Component)searchInputField).gameObject.SetActive(false);
			((Component)searchInputField).gameObject.SetActive(true);
		}

		private TMP_InputField CreateInputField(string placeholder, Vector2 position)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI component = GameObject.Find("/Canvas/MenuContainer/LobbyList/ListPanel/ListHeader").GetComponent<TextMeshProUGUI>();
			GameObject val = new GameObject("SearchInputField");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = position;
			TMP_InputField val3 = val.AddComponent<TMP_InputField>();
			((Selectable)val3).interactable = true;
			GameObject val4 = new GameObject("Placeholder");
			val4.transform.SetParent(val.transform, false);
			TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val5).text = placeholder;
			((TMP_Text)val5).font = ((TMP_Text)component).font;
			((Graphic)val5).color = ((Graphic)component).color;
			val3.placeholder = (Graphic)(object)val5;
			GameObject val6 = new GameObject("Text");
			val6.transform.SetParent(val.transform, false);
			TextMeshProUGUI val7 = val6.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val7).font = ((TMP_Text)component).font;
			((Graphic)val7).color = ((Graphic)component).color;
			val3.textComponent = (TMP_Text)(object)val7;
			RectTransform component2 = ((Component)val3).GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(200f, 30f);
			component2.anchoredPosition = new Vector2(0f, 0f);
			return val3;
		}

		private void OnEndEdit(string newValue)
		{
			Text = newValue;
			ModNotifyBase.Logger.LogInfo((object)("SearchBox: Search Value Changed - " + newValue));
			SteamLobbyManager val = Object.FindObjectOfType<SteamLobbyManager>();
			val.LoadServerList();
		}
	}
}

BepInEx/plugins/CoilHeadStare.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using TDP.CoilHeadStare.Patch;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CoilHeadStare")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CoilHeadStare")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9d96f0c2-6393-4d02-99d7-34538a0dad5c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TDP.CoilHeadStare
{
	[BepInPlugin("TDP.CoilHeadStare", "CoilHeadStare", "1.0.3")]
	public class ModBase : BaseUnityPlugin
	{
		private const string modGUID = "TDP.CoilHeadStare";

		private const string modName = "CoilHeadStare";

		private const string modVersion = "1.0.3";

		private Harmony harmony;

		internal static ModBase instance;

		internal ManualLogSource mls;

		public static ConfigEntry<float> config_timeUntilStare;

		public static ConfigEntry<float> config_maxStareDistance;

		public static ConfigEntry<float> config_turnHeadSpeed;

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			else
			{
				Object.Destroy((Object)(object)this);
			}
			ConfigFile();
			harmony = new Harmony("TDP.CoilHeadStare");
			harmony.PatchAll(typeof(CoilHeadPatch));
			mls = Logger.CreateLogSource("TDP.CoilHeadStare");
			mls.LogInfo((object)"CoilHeadStare 1.0.3 loaded.");
		}

		private void ConfigFile()
		{
			config_timeUntilStare = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Time Until Stare", 8f, "Time between moving and looking at closest player (in seconds)");
			config_maxStareDistance = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Max Stare Distance", 6f, "Coilhead will only stare at players closer than this (for reference: coilhead's height is ca. 4)");
			config_turnHeadSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Head Turn Speed", 0.3f, "The speed at which the head turns towards the player");
			Stare.timeUntilStare = config_timeUntilStare.Value;
			Stare.maxStareDistance = config_maxStareDistance.Value;
			Stare.turnHeadSpeed = config_turnHeadSpeed.Value;
		}

		private void ConfigureDoorControls()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0041: 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)
			GameObject val = GameObject.Find("HangarDoorButtonPanel");
			GameObject val2 = new GameObject("PlacementCollider");
			val2.transform.SetParent(val.transform, false);
			BoxCollider val3 = val2.AddComponent<BoxCollider>();
			val3.size = new Vector3(0.881444f, 0.147624f, 0.7243316f);
			val3.center = new Vector3(0.2525222f, 0.06033165f, -0.06168448f);
			PlaceableShipObject val4 = val2.AddComponent<PlaceableShipObject>();
			val4.unlockableID = 1212;
			val4.parentObject = val.AddComponent<AutoParentToShip>();
			val4.mainMesh = val.GetComponent<MeshFilter>();
			val4.mainTransform = val.transform;
			val4.placeObjectCollider = (Collider)(object)val3;
			val4.yOffset = 0f;
			val4.AllowPlacementOnWalls = true;
			val2.AddComponent<AudioSource>();
		}
	}
}
namespace TDP.CoilHeadStare.Patch
{
	internal class CoilHeadPatch
	{
		[HarmonyPatch(typeof(EnemyAI), "Start")]
		[HarmonyPostfix]
		private static void StartPostFix(EnemyAI __instance)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (__instance is SpringManAI)
			{
				Debug.Log((object)"CoilHead found. Adding stare script.");
				Stare stare = ((Component)__instance).gameObject.AddComponent<Stare>();
				stare.Initialize((SpringManAI)__instance);
			}
		}
	}
	public class Stare : MonoBehaviour
	{
		private SpringManAI coilHeadInstance;

		public static float timeUntilStare;

		public static float maxStareDistance;

		public static float turnHeadSpeed;

		private Transform head;

		private float timeSinceMoving;

		private bool isTurningHead;

		private PlayerControllerB stareTarget;

		public void Initialize(SpringManAI instance)
		{
			Debug.Log((object)"Initializing Stare on Coilhead.");
			coilHeadInstance = instance;
			head = ((Component)coilHeadInstance).transform.GetChild(0).GetChild(2).GetChild(0)
				.GetChild(0)
				.GetChild(0)
				.GetChild(0)
				.GetChild(0)
				.GetChild(2)
				.GetChild(0)
				.GetChild(0)
				.GetChild(1);
			if (((Object)head).name != "springBone.002_end")
			{
				Debug.LogError((object)"CoilHeadStare could not find head transform. Destroying script.");
				Object.Destroy((Object)(object)this);
			}
		}

		private void Update()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)coilHeadInstance == (Object)null)
			{
				return;
			}
			if ((Object)(object)head == (Object)null)
			{
				Debug.LogError((object)"CoilHeadStare head transform missing. Destroying script.");
				Object.Destroy((Object)(object)this);
				return;
			}
			if (!isTurningHead)
			{
				stareTarget = ((EnemyAI)coilHeadInstance).GetClosestPlayer(false, false, false);
			}
			if (!((Object)(object)stareTarget == (Object)null))
			{
				Vector3 val = ((Component)stareTarget.gameplayCamera).transform.position - head.position;
				float num = Vector3.Distance(head.position, ((Component)((EnemyAI)coilHeadInstance).GetClosestPlayer(false, false, false)).transform.position);
				if ((double)((EnemyAI)coilHeadInstance).creatureAnimator.GetFloat("walkSpeed") > 0.01 || num > maxStareDistance || Vector3.Angle(head.forward, val) < 5f)
				{
					timeSinceMoving = 0f;
				}
				else
				{
					timeSinceMoving += Time.deltaTime;
				}
				if (timeSinceMoving > timeUntilStare)
				{
					isTurningHead = true;
				}
				else
				{
					isTurningHead = false;
				}
				if (isTurningHead)
				{
					head.forward = Vector3.RotateTowards(head.forward, val, turnHeadSpeed * Time.deltaTime, 0f);
				}
			}
		}
	}
}

BepInEx/plugins/ChillaxMods.dll

Decompiled 8 months 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChillaxMods")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Chillax Mods")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ChillaxMods")]
[assembly: AssemblyTitle("ChillaxMods")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ChillaxMods
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ChillaxMods";

		public const string PLUGIN_NAME = "ChillaxMods";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Chillax.Bastard.BogBog
{
	public class Boink : NoisemakerProp
	{
		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null))
			{
				PlayerControllerB playerHeldBy = ((GrabbableObject)this).playerHeldBy;
				Vector3 val = -((Component)this).transform.forward + Vector3.up;
				playerHeldBy.externalForces = ((Vector3)(ref val)).normalized * 500f;
				ChillaxModPlugin.logger.LogInfo((object)"[CHILLAX] ACTIVATE BOINK!");
				((NoisemakerProp)this).ItemActivate(used, buttonDown);
			}
		}

		protected override void __initializeVariables()
		{
			((NoisemakerProp)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "Boink";
		}
	}
	[BepInPlugin("chillax.bastard.mod", "Chillax Mods", "0.5.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ChillaxModPlugin : BaseUnityPlugin
	{
		public static ManualLogSource logger;

		public const string PluginGuid = "chillax.bastard.mod";

		public const string PluginName = "Chillax Mods";

		public const string PluginVersion = "0.5.2";

		public static readonly Harmony harmony = new Harmony("chillax.bastard.mod");

		public static ConfigFile config;

		public void Awake()
		{
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			Config.Load();
			Content.Load();
			harmony.PatchAll(typeof(ChillaxModPlugin));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CHILLAX Plugin Loaded");
		}
	}
	public class Config
	{
		public static ConfigEntry<int> boinkSpawnChance;

		public static ConfigEntry<int> cupNoodleSpawnChance;

		public static ConfigEntry<int> freddySpawnChance;

		public static ConfigEntry<int> nokiaSpawnChance;

		public static ConfigEntry<int> moaiSpawnChance;

		public static ConfigEntry<int> froggySpawnChance;

		public static ConfigEntry<int> eeveeSpawnChance;

		public static ConfigEntry<int> deathNoteSpawnChance;

		public static ConfigEntry<int> unoReverseSpawnChance;

		public static ConfigEntry<bool> canUseDeathNote;

		public static void Load()
		{
			boinkSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Boink", 30, "How much does this Item spawn, higher = more common");
			cupNoodleSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "CupNoodle", 40, "How much does this Item spawn, higher = more common");
			freddySpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Freddy", 15, "How much does this Item spawn, higher = more common");
			nokiaSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Nokia", 30, "How much does this Item spawn, higher = more common");
			moaiSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Moai", 20, "How much does this Item spawn, higher = more common");
			froggySpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Froggy", 30, "How much does this Item spawn, higher = more common");
			eeveeSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "Eevee", 30, "How much does this Item spawn, higher = more common");
			deathNoteSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "DeathNote", 20, "How much does this Item spawn, higher = more common");
			canUseDeathNote = ChillaxModPlugin.config.Bind<bool>("Death Note", "DeathNoteActive", true, "Can the Death Note be used, turn this off to avoid griefing");
			unoReverseSpawnChance = ChillaxModPlugin.config.Bind<int>("Scrap", "UnoReverse", 20, "How much does this Item spawn, higher = more common");
		}
	}
	public class Content
	{
		public class CustomItem
		{
			public string name = "";

			public string itemPath = "";

			public string infoPath = "";

			public Action<Item> itemAction = delegate
			{
			};

			public bool enabled = true;

			public CustomItem(string name, string itemPath, string infoPath, Action<Item> action = null)
			{
				this.name = name;
				this.itemPath = itemPath;
				this.infoPath = infoPath;
				if (action != null)
				{
					itemAction = action;
				}
			}

			public static CustomItem Add(string name, string itemPath, string infoPath = null, Action<Item> action = null)
			{
				return new CustomItem(name, itemPath, infoPath, action);
			}
		}

		public class CustomUnlockable
		{
			public string name = "";

			public string unlockablePath = "";

			public string infoPath = "";

			public Action<UnlockableItem> unlockableAction = delegate
			{
			};

			public bool enabled = true;

			public int unlockCost = -1;

			public CustomUnlockable(string name, string unlockablePath, string infoPath, Action<UnlockableItem> action = null, int unlockCost = -1)
			{
				this.name = name;
				this.unlockablePath = unlockablePath;
				this.infoPath = infoPath;
				if (action != null)
				{
					unlockableAction = action;
				}
				this.unlockCost = unlockCost;
			}

			public static CustomUnlockable Add(string name, string unlockablePath, string infoPath = null, Action<UnlockableItem> action = null, int unlockCost = -1, bool enabled = true)
			{
				return new CustomUnlockable(name, unlockablePath, infoPath, action, unlockCost)
				{
					enabled = enabled
				};
			}
		}

		public class CustomShopItem : CustomItem
		{
			public int itemPrice;

			public CustomShopItem(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null)
				: base(name, itemPath, infoPath, action)
			{
				this.itemPrice = itemPrice;
			}

			public static CustomShopItem Add(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null, bool enabled = true)
			{
				CustomShopItem customShopItem = new CustomShopItem(name, itemPath, infoPath, itemPrice, action);
				customShopItem.enabled = enabled;
				return customShopItem;
			}
		}

		public class CustomScrap : CustomItem
		{
			public LevelTypes levelType = (LevelTypes)510;

			public int rarity;

			public CustomScrap(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null)
				: base(name, itemPath, null, action)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				this.levelType = levelType;
				this.rarity = rarity;
			}

			public static CustomScrap Add(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				return new CustomScrap(name, itemPath, levelType, rarity, action);
			}
		}

		public class CustomEnemy
		{
			public string name;

			public string enemyPath;

			public int rarity;

			public LevelTypes levelFlags;

			public SpawnType spawnType;

			public string infoKeyword;

			public string infoNode;

			public bool enabled = true;

			public CustomEnemy(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: 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_002f: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.enemyPath = enemyPath;
				this.rarity = rarity;
				this.levelFlags = levelFlags;
				this.spawnType = spawnType;
				this.infoKeyword = infoKeyword;
				this.infoNode = infoNode;
			}

			public static CustomEnemy Add(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode, bool enabled = true)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return new CustomEnemy(name, enemyPath, rarity, levelFlags, spawnType, infoKeyword, infoNode)
				{
					enabled = enabled
				};
			}
		}

		public class CustomMapObject
		{
			public string name;

			public string objectPath;

			public LevelTypes levelFlags;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public bool enabled = true;

			public CustomMapObject(string name, string objectPath, LevelTypes levelFlags, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, bool enabled = false)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.objectPath = objectPath;
				this.levelFlags = levelFlags;
				this.spawnRateFunction = spawnRateFunction;
				this.enabled = enabled;
			}

			public static CustomMapObject Add(string name, string objectPath, LevelTypes levelFlags, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, bool enabled = false)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				return new CustomMapObject(name, objectPath, levelFlags, spawnRateFunction, enabled);
			}
		}

		public static AssetBundle MainAssets;

		public static Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		public static List<CustomUnlockable> customUnlockables;

		public static List<CustomItem> customItems;

		public static List<CustomEnemy> customEnemies;

		public static List<CustomMapObject> customMapObjects;

		public static GameObject ConfigManagerPrefab;

		public static void TryLoadAssets()
		{
			if ((Object)(object)MainAssets == (Object)null)
			{
				MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "chillaxBundle"));
				Plugin.logger.LogInfo((object)"Loaded asset bundle");
			}
		}

		public static void Load()
		{
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			TryLoadAssets();
			customItems = new List<CustomItem>
			{
				CustomScrap.Add("Boink", "Assets/Chillax/ChillaxMods/Boink/Boink.asset", (LevelTypes)510, Config.boinkSpawnChance.Value),
				CustomScrap.Add("MamaMooSup", "Assets/Chillax/ChillaxMods/Cup Noodle/Cup Noodle.asset", (LevelTypes)510, Config.cupNoodleSpawnChance.Value),
				CustomScrap.Add("Freddy", "Assets/Chillax/ChillaxMods/FreddyFastBear/Freddy.asset", (LevelTypes)510, Config.freddySpawnChance.Value),
				CustomScrap.Add("Nokia", "Assets/Chillax/ChillaxMods/Nokia/Nokia.asset", (LevelTypes)510, Config.nokiaSpawnChance.Value),
				CustomScrap.Add("Moai", "Assets/Chillax/ChillaxMods/Moai/Moai.asset", (LevelTypes)510, Config.moaiSpawnChance.Value),
				CustomScrap.Add("Froggy", "Assets/Chillax/ChillaxMods/Froggy Chair/Froggy Chair.asset", (LevelTypes)510, Config.froggySpawnChance.Value),
				CustomScrap.Add("Eevee", "Assets/Chillax/ChillaxMods/Eevee Plush/Eevee.asset", (LevelTypes)510, Config.eeveeSpawnChance.Value),
				CustomScrap.Add("DeathNote", "Assets/Chillax/ChillaxMods/DeathNote/DeathNote.asset", (LevelTypes)510, Config.deathNoteSpawnChance.Value),
				CustomScrap.Add("UnoReverse", "Assets/Chillax/ChillaxMods/UnoReverse/UnoReverse.asset", (LevelTypes)510, Config.unoReverseSpawnChance.Value)
			};
			customEnemies = new List<CustomEnemy>();
			customUnlockables = new List<CustomUnlockable>();
			customMapObjects = new List<CustomMapObject>();
			foreach (CustomItem customItem in customItems)
			{
				if (customItem.enabled)
				{
					Item val = MainAssets.LoadAsset<Item>(customItem.itemPath);
					if ((Object)(object)val.spawnPrefab.GetComponent<NetworkTransform>() == (Object)null)
					{
						val.spawnPrefab.AddComponent<NetworkTransform>();
					}
					Prefabs.Add(customItem.name, val.spawnPrefab);
					NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
					customItem.itemAction(val);
					if (customItem is CustomShopItem)
					{
						TerminalNode val2 = MainAssets.LoadAsset<TerminalNode>(customItem.infoPath);
						Plugin.logger.LogInfo((object)$"Registering shop item {customItem.name} with price {((CustomShopItem)customItem).itemPrice}");
						Items.RegisterShopItem(val, (TerminalNode)null, (TerminalNode)null, val2, ((CustomShopItem)customItem).itemPrice);
					}
					else if (customItem is CustomScrap customScrap)
					{
						ChillaxModPlugin.logger.LogInfo((object)$"[CHILLAX] Registering... {val.itemName} at rarity {customScrap.rarity}");
						Items.RegisterScrap(val, customScrap.rarity, customScrap.levelType);
					}
				}
			}
			foreach (CustomUnlockable customUnlockable in customUnlockables)
			{
				if (customUnlockable.enabled)
				{
					UnlockableItem unlockable = MainAssets.LoadAsset<UnlockableItemDef>(customUnlockable.unlockablePath).unlockable;
					if ((Object)(object)unlockable.prefabObject != (Object)null)
					{
						NetworkPrefabs.RegisterNetworkPrefab(unlockable.prefabObject);
					}
					Prefabs.Add(customUnlockable.name, unlockable.prefabObject);
					TerminalNode val3 = null;
					if (customUnlockable.infoPath != null)
					{
						val3 = MainAssets.LoadAsset<TerminalNode>(customUnlockable.infoPath);
					}
					Unlockables.RegisterUnlockable(unlockable, (StoreType)2, (TerminalNode)null, (TerminalNode)null, val3, customUnlockable.unlockCost);
				}
			}
			foreach (CustomEnemy customEnemy in customEnemies)
			{
				if (customEnemy.enabled)
				{
					EnemyType val4 = MainAssets.LoadAsset<EnemyType>(customEnemy.enemyPath);
					TerminalNode val5 = MainAssets.LoadAsset<TerminalNode>(customEnemy.infoNode);
					TerminalKeyword val6 = null;
					if (customEnemy.infoKeyword != null)
					{
						val6 = MainAssets.LoadAsset<TerminalKeyword>(customEnemy.infoKeyword);
					}
					NetworkPrefabs.RegisterNetworkPrefab(val4.enemyPrefab);
					Prefabs.Add(customEnemy.name, val4.enemyPrefab);
					Enemies.RegisterEnemy(val4, customEnemy.rarity, customEnemy.levelFlags, customEnemy.spawnType, val5, val6);
				}
			}
			foreach (CustomMapObject customMapObject in customMapObjects)
			{
				if (customMapObject.enabled)
				{
					SpawnableMapObjectDef val7 = MainAssets.LoadAsset<SpawnableMapObjectDef>(customMapObject.objectPath);
					NetworkPrefabs.RegisterNetworkPrefab(val7.spawnableMapObject.prefabToSpawn);
					Prefabs.Add(customMapObject.name, val7.spawnableMapObject.prefabToSpawn);
					MapObjects.RegisterMapObject(val7, customMapObject.levelFlags, customMapObject.spawnRateFunction);
				}
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			Plugin.logger.LogInfo((object)"[CHILLAX] Custom content loaded!");
		}
	}
	public class DeathNote : NoisemakerProp
	{
		private NetworkVariable<bool> canUseDeathNote = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		[SerializeField]
		private AudioClip killSfx;

		[SerializeField]
		private GameObject canvasPrefab;

		private float _currentCooldown;

		[SerializeField]
		private float checkRate;

		[SerializeField]
		private Renderer deathNoteRenderer;

		[SerializeField]
		private Material[] materials;

		[SerializeField]
		private string[] textNodes;

		[SerializeField]
		private Sprite[] icons;

		[SerializeField]
		private ScanNodeProperties scanNodeProperties;

		private DeathNoteCanvas _temp;

		public List<PlayerControllerB> playerList;

		public List<EnemyAI> enemyList;

		private bool _opened;

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			canUseDeathNote = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);
			playerList = new List<PlayerControllerB>();
			enemyList = new List<EnemyAI>();
			Item itemProperties = Object.Instantiate<Item>(((GrabbableObject)this).itemProperties);
			((GrabbableObject)this).itemProperties = itemProperties;
			UpdateList();
			_opened = false;
			((MonoBehaviour)this).InvokeRepeating("ProcessCooldown", checkRate, checkRate);
			if (((NetworkBehaviour)this).IsHost)
			{
				canUseDeathNote.Value = Config.canUseDeathNote.Value;
				UpdateVisuals(0);
				UpdateVisualsClientRpc(0);
			}
		}

		[ClientRpc]
		private void UpdateVisualsClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(531245751u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 531245751u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					UpdateVisuals(index);
				}
			}
		}

		private void UpdateVisuals(int index)
		{
			if ((Object)(object)deathNoteRenderer.material != (Object)(object)materials[index])
			{
				deathNoteRenderer.material = materials[index];
			}
			scanNodeProperties.headerText = textNodes[index];
			((GrabbableObject)this).itemProperties.itemName = textNodes[index];
			((GrabbableObject)this).itemProperties.itemIcon = icons[index];
		}

		[ServerRpc(RequireOwnership = false)]
		private void StartCooldownServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(246655775u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 246655775u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Random random = new Random();
					StartCooldownClientRpc(_currentCooldown = random.Next(600, 1800));
				}
			}
		}

		[ClientRpc]
		private void StartCooldownClientRpc(float cooldown)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(316831956u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref cooldown, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 316831956u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					_currentCooldown = cooldown;
				}
			}
		}

		private void ProcessCooldown()
		{
			if (_currentCooldown > 0f)
			{
				_currentCooldown -= checkRate;
				UpdateVisuals(1);
			}
			else
			{
				UpdateVisuals(0);
			}
		}

		private void UpdateList()
		{
			playerList = Object.FindObjectsOfType<PlayerControllerB>().ToList();
			enemyList = Object.FindObjectsOfType<EnemyAI>().ToList();
		}

		private void OnDisable()
		{
			if ((Object)(object)_temp != (Object)null)
			{
				_temp.Close();
			}
		}

		public override void DiscardItem()
		{
			((GrabbableObject)this).DiscardItem();
			if ((Object)(object)_temp != (Object)null)
			{
				_temp.Close();
			}
		}

		public override void PocketItem()
		{
			((GrabbableObject)this).PocketItem();
			if ((Object)(object)_temp != (Object)null)
			{
				_temp.Close();
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (canUseDeathNote.Value && !_opened && !(_currentCooldown > 0f))
			{
				((NoisemakerProp)this).ItemActivate(used, buttonDown);
				if (((NetworkBehaviour)((GrabbableObject)this).playerHeldBy).IsOwner)
				{
					UpdateList();
					_temp = Object.Instantiate<GameObject>(canvasPrefab, ((Component)this).transform).GetComponent<DeathNoteCanvas>();
					_temp.Initialize(this);
					_opened = true;
					Cursor.visible = true;
					Cursor.lockState = (CursorLockMode)0;
					DeathNoteCanvas temp = _temp;
					temp.onExit = (Action)Delegate.Combine(temp.onExit, new Action(OnExit));
				}
			}
		}

		private void OnExit()
		{
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
			_opened = false;
		}

		public void ActivateDeathNote(GameObject objectToKill)
		{
			OnExit();
			if (Object.op_Implicit((Object)(object)objectToKill.GetComponent<PlayerControllerB>()))
			{
				KillPlayer(objectToKill.GetComponent<PlayerControllerB>());
			}
			if (Object.op_Implicit((Object)(object)objectToKill.GetComponent<EnemyAI>()))
			{
				KillEnemy(objectToKill.GetComponent<EnemyAI>());
			}
			StartCooldownServerRpc();
		}

		private void KillPlayer(PlayerControllerB controller)
		{
			if (!((Object)(object)controller == (Object)null))
			{
				Debug.Log((object)("[CHILLAX] [DEATH NOTE] killing off player: " + controller.playerUsername));
				DeathNoteServerRpc(controller.playerClientId, ((NetworkBehaviour)controller).OwnerClientId);
			}
		}

		private void KillEnemy(EnemyAI enemy)
		{
			if (!((Object)(object)enemy == (Object)null))
			{
				Debug.Log((object)("[CHILLAX] [DEATH NOTE] killing off enemy: " + enemy.enemyType.enemyName));
				enemy.KillEnemyServerRpc(false);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void DeathNoteServerRpc(ulong playerID, ulong clientID)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2937588739u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerID);
					BytePacker.WriteValueBitPacked(val2, clientID);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2937588739u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					PlayerControllerB component = StartOfRound.Instance.allPlayerObjects[playerID].GetComponent<PlayerControllerB>();
					Debug.Log((object)("[DEATH NOTE] Receive Server RPC, player to kill: " + component.playerUsername));
					ClientRpcParams val3 = default(ClientRpcParams);
					val3.Send = new ClientRpcSendParams
					{
						TargetClientIds = new ulong[1] { clientID }
					};
					ClientRpcParams clientRpcParams = val3;
					DeathNoteClientRpc(component.playerClientId, clientRpcParams);
				}
			}
		}

		[ClientRpc]
		private void DeathNoteClientRpc(ulong playerID, ClientRpcParams clientRpcParams = default(ClientRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2281964886u, clientRpcParams, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val, playerID);
					((NetworkBehaviour)this).__endSendClientRpc(ref val, 2281964886u, clientRpcParams, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlayerControllerB component = StartOfRound.Instance.allPlayerObjects[playerID].GetComponent<PlayerControllerB>();
					Debug.Log((object)("[DEATH NOTE] Receive Client RPC, player to kill: " + component.playerUsername));
					Debug.Log((object)("[DEATH NOTE] Killing: " + component.playerUsername));
					((MonoBehaviour)this).StartCoroutine(KilLDelay(component));
				}
			}
		}

		private IEnumerator KilLDelay(PlayerControllerB controller)
		{
			if (((NetworkBehaviour)controller).IsOwner)
			{
				AudioSource tempSource = ((Component)controller).gameObject.AddComponent<AudioSource>();
				tempSource.PlayOneShot(killSfx);
				Object.Destroy((Object)(object)tempSource, 3f);
			}
			yield return (object)new WaitForSeconds(3f);
			controller.KillPlayer(Vector3.up * 10f, true, (CauseOfDeath)0, 0);
		}

		protected override void __initializeVariables()
		{
			if (canUseDeathNote == null)
			{
				throw new Exception("DeathNote.canUseDeathNote cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)canUseDeathNote).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)canUseDeathNote, "canUseDeathNote");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)canUseDeathNote);
			((NoisemakerProp)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_DeathNote()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(531245751u, new RpcReceiveHandler(__rpc_handler_531245751));
			NetworkManager.__rpc_func_table.Add(246655775u, new RpcReceiveHandler(__rpc_handler_246655775));
			NetworkManager.__rpc_func_table.Add(316831956u, new RpcReceiveHandler(__rpc_handler_316831956));
			NetworkManager.__rpc_func_table.Add(2937588739u, new RpcReceiveHandler(__rpc_handler_2937588739));
			NetworkManager.__rpc_func_table.Add(2281964886u, new RpcReceiveHandler(__rpc_handler_2281964886));
		}

		private static void __rpc_handler_531245751(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int index = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref index);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((DeathNote)(object)target).UpdateVisualsClientRpc(index);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_246655775(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((DeathNote)(object)target).StartCooldownServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_316831956(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				float cooldown = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref cooldown, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((DeathNote)(object)target).StartCooldownClientRpc(cooldown);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2937588739(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerID = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerID);
				ulong clientID = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientID);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((DeathNote)(object)target).DeathNoteServerRpc(playerID, clientID);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2281964886(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerID = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerID);
				ClientRpcParams client = rpcParams.Client;
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((DeathNote)(object)target).DeathNoteClientRpc(playerID, client);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "DeathNote";
		}
	}
	public class DeathNoteCanvas : MonoBehaviour
	{
		[SerializeField]
		private Button closeButton;

		[SerializeField]
		private GameObject namesPrefab;

		[SerializeField]
		private Transform contentContainer;

		private string _chosenName;

		private DeathNote _deathNote;

		public Action onExit;

		public void Initialize(DeathNote deathNote)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			foreach (Transform item in contentContainer)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			((UnityEvent)closeButton.onClick).AddListener(new UnityAction(Close));
			_deathNote = deathNote;
			onExit = (Action)Delegate.Combine(onExit, new Action(OnExit));
			foreach (PlayerControllerB player in deathNote.playerList)
			{
				if (!player.isPlayerDead)
				{
					DeathNoteName component = Object.Instantiate<GameObject>(namesPrefab, contentContainer).GetComponent<DeathNoteName>();
					component.Initialize(((Component)player).gameObject, _deathNote, this);
				}
			}
			foreach (EnemyAI enemy in deathNote.enemyList)
			{
				if (!enemy.isEnemyDead && enemy.enemyType.canDie)
				{
					DeathNoteName component2 = Object.Instantiate<GameObject>(namesPrefab, contentContainer).GetComponent<DeathNoteName>();
					component2.Initialize(((Component)enemy).gameObject, _deathNote, this);
				}
			}
		}

		private void OnExit()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		public void Close()
		{
			onExit?.Invoke();
		}
	}
	public class DeathNoteName : MonoBehaviour
	{
		[SerializeField]
		private TMP_Text nameText;

		[SerializeField]
		private Button killButton;

		private GameObject _objectToKill;

		private DeathNote _deathNote;

		private DeathNoteCanvas _deathNoteCanvas;

		public void Initialize(GameObject objectToKill, DeathNote deathNote, DeathNoteCanvas deathNoteCanvas)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			_deathNote = deathNote;
			_objectToKill = objectToKill;
			_deathNoteCanvas = deathNoteCanvas;
			if (Object.op_Implicit((Object)(object)objectToKill.GetComponent<PlayerControllerB>()))
			{
				nameText.text = objectToKill.GetComponent<PlayerControllerB>().playerUsername;
			}
			else
			{
				nameText.text = ((object)objectToKill.GetComponent<EnemyAI>().enemyType).ToString();
			}
			((UnityEvent)killButton.onClick).AddListener(new UnityAction(Kill));
		}

		private void Kill()
		{
			_deathNote.ActivateDeathNote(_objectToKill);
			_deathNoteCanvas.Close();
		}
	}
	public class Food : NoisemakerProp
	{
		[SerializeField]
		private int healAmount;

		[SerializeField]
		private float refuelAmount;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (!((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null))
			{
				if (((GrabbableObject)this).playerHeldBy.sprintMeter + refuelAmount > 1f)
				{
					((GrabbableObject)this).playerHeldBy.sprintMeter = 1f;
				}
				else
				{
					PlayerControllerB playerHeldBy = ((GrabbableObject)this).playerHeldBy;
					playerHeldBy.sprintMeter += refuelAmount;
				}
				if (((GrabbableObject)this).playerHeldBy.health + healAmount > 100)
				{
					((GrabbableObject)this).playerHeldBy.health = 100;
				}
				else
				{
					PlayerControllerB playerHeldBy2 = ((GrabbableObject)this).playerHeldBy;
					playerHeldBy2.health += healAmount;
				}
				((MonoBehaviour)this).StartCoroutine(DestroyDelay());
				ChillaxModPlugin.logger.LogInfo((object)"[CHILLAX] EAT FOOD!!");
				((NoisemakerProp)this).ItemActivate(used, buttonDown);
			}
		}

		private IEnumerator DestroyDelay()
		{
			yield return (object)new WaitForSeconds(0.5f);
			((GrabbableObject)this).DestroyObjectInHand(((GrabbableObject)this).playerHeldBy);
		}

		protected override void __initializeVariables()
		{
			((NoisemakerProp)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "Food";
		}
	}
	public class UnoReverse : NoisemakerProp
	{
		public AudioClip teleportClip;

		public List<PlayerControllerB> playerList;

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			playerList = new List<PlayerControllerB>();
		}

		private void UpdatePlayerList()
		{
			playerList = Object.FindObjectsOfType<PlayerControllerB>().ToList();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			((NoisemakerProp)this).ItemActivate(used, buttonDown);
			UpdatePlayerList();
			foreach (PlayerControllerB player in playerList)
			{
				Debug.Log((object)("[CHILLAX] [UNO REVERSE] Players in Game: " + player.playerUsername));
			}
			playerList.Remove(((GrabbableObject)this).playerHeldBy);
			int index = Random.Range(0, playerList.Count);
			if (playerList.Count <= 0)
			{
				Debug.LogWarning((object)"[CHILLAX] [UNO REVERSE] No players to swap with");
			}
			foreach (PlayerControllerB player2 in playerList)
			{
				Debug.Log((object)("[CHILLAX] [UNO REVERSE] Potential Swappers: " + player2.playerUsername));
			}
			PlayerControllerB val = playerList[index];
			Vector3 serverPlayerPosition = ((GrabbableObject)this).playerHeldBy.serverPlayerPosition;
			Vector3 serverPlayerPosition2 = val.serverPlayerPosition;
			SwapServerRpc(serverPlayerPosition, serverPlayerPosition2, ((NetworkBehaviour)val).OwnerClientId);
			((MonoBehaviour)this).StartCoroutine(DestroyDelay());
		}

		[ServerRpc(RequireOwnership = false)]
		private void SwapServerRpc(Vector3 firstPosition, Vector3 secondPosition, ulong otherId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1423553523u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref firstPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref secondPosition);
					BytePacker.WriteValueBitPacked(val2, otherId);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1423553523u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Teleport(firstPosition, secondPosition, otherId);
				}
			}
		}

		private void Teleport(Vector3 firstPosition, Vector3 secondPosition, ulong otherId)
		{
			//IL_0003: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			ClientRpcParams val = default(ClientRpcParams);
			val.Send = new ClientRpcSendParams
			{
				TargetClientIds = new ulong[1] { ((NetworkBehaviour)((GrabbableObject)this).playerHeldBy).OwnerClientId }
			};
			ClientRpcParams clientRpcParams = val;
			val = default(ClientRpcParams);
			val.Send = new ClientRpcSendParams
			{
				TargetClientIds = new ulong[1] { otherId }
			};
			ClientRpcParams clientRpcParams2 = val;
			TeleportOnClientRpc(secondPosition, clientRpcParams);
			TeleportOnClientRpc(firstPosition, clientRpcParams2);
			PlayExtraClipClientRpc(clientRpcParams2);
		}

		[ClientRpc]
		private void TeleportOnClientRpc(Vector3 position, ClientRpcParams clientRpcParams = default(ClientRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(40319756u, clientRpcParams, (RpcDelivery)0);
					((FastBufferWriter)(ref val)).WriteValueSafe(ref position);
					((NetworkBehaviour)this).__endSendClientRpc(ref val, 40319756u, clientRpcParams, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					StartOfRound.Instance.localPlayerController.TeleportPlayer(position, false, 0f, false, true);
				}
			}
		}

		[ClientRpc]
		private void PlayExtraClipClientRpc(ClientRpcParams clientRpcParams = default(ClientRpcParams))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(457107265u, clientRpcParams, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 457107265u, clientRpcParams, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				AudioSource val2 = ((Component)StartOfRound.Instance.localPlayerController).gameObject.AddComponent<AudioSource>();
				if (!((Object)(object)teleportClip == (Object)null))
				{
					val2.PlayOneShot(teleportClip);
					Object.Destroy((Object)(object)val2, 2f);
				}
			}
		}

		private IEnumerator DestroyDelay()
		{
			yield return (object)new WaitForSeconds(1f);
			((GrabbableObject)this).DestroyObjectInHand(((GrabbableObject)this).playerHeldBy);
			DestroyServerRpc();
		}

		[ServerRpc(RequireOwnership = false)]
		private void DestroyServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3051293639u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3051293639u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					((GrabbableObject)this).DestroyObjectInHand(((GrabbableObject)this).playerHeldBy);
					DestroyClientRpc();
				}
			}
		}

		[ClientRpc]
		private void DestroyClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1058296590u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1058296590u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((GrabbableObject)this).DestroyObjectInHand(((GrabbableObject)this).playerHeldBy);
				}
			}
		}

		protected override void __initializeVariables()
		{
			((NoisemakerProp)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_UnoReverse()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1423553523u, new RpcReceiveHandler(__rpc_handler_1423553523));
			NetworkManager.__rpc_func_table.Add(40319756u, new RpcReceiveHandler(__rpc_handler_40319756));
			NetworkManager.__rpc_func_table.Add(457107265u, new RpcReceiveHandler(__rpc_handler_457107265));
			NetworkManager.__rpc_func_table.Add(3051293639u, new RpcReceiveHandler(__rpc_handler_3051293639));
			NetworkManager.__rpc_func_table.Add(1058296590u, new RpcReceiveHandler(__rpc_handler_1058296590));
		}

		private static void __rpc_handler_1423553523(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 firstPosition = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref firstPosition);
				Vector3 secondPosition = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref secondPosition);
				ulong otherId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref otherId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((UnoReverse)(object)target).SwapServerRpc(firstPosition, secondPosition, otherId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_40319756(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 position = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
				ClientRpcParams client = rpcParams.Client;
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((UnoReverse)(object)target).TeleportOnClientRpc(position, client);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_457107265(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ClientRpcParams client = rpcParams.Client;
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((UnoReverse)(object)target).PlayExtraClipClientRpc(client);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3051293639(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((UnoReverse)(object)target).DestroyServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1058296590(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((UnoReverse)(object)target).DestroyClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "UnoReverse";
		}
	}
}

BepInEx/plugins/StockOverview.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using TerminalApi;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("StockOverview")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("StockOverview")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e51b9040-4911-42f8-8c25-b79b34a4965a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace StockOverview;

public static class PluginInfo
{
	public const string PLUGIN_NAME = "StockOverview";

	public const string PLUGIN_VERSION = "1.0.3";

	public const string PLUGIN_GUID = "squall4120.stockoverview";
}
[BepInPlugin("squall4120.stockoverview", "StockOverview", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class StockOverview : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin StockOverview is loaded!");
		Harmony val = new Harmony("squall4120.stockoverview");
		val.PatchAll(Assembly.GetExecutingAssembly());
		TerminalNode val2 = TerminalApi.CreateTerminalNode("Scanning for scrap on ship...\n", true, "stockoverview");
		TerminalKeyword val3 = TerminalApi.CreateTerminalKeyword("stock", true, val2);
		TerminalApi.AddTerminalKeyword(val3);
	}

	public static string BuildOverview()
	{
		string displayText = "STOCK OVERVIEW\n\n";
		IEnumerable<GrabbableObject> source = from obj in GameObject.Find("/Environment/HangarShip").GetComponentsInChildren<GrabbableObject>()
			where ((Object)obj).name != "ClipboardManual" && ((Object)obj).name != "StickyNoteItem"
			select obj;
		string format = "Quantity of all items: {0}";
		string format2 = "Total value of all items: ${0:F0}";
		displayText = displayText + string.Format(format, source.Count()) + "\n";
		displayText = displayText + string.Format(format2, source.Sum((GrabbableObject item) => item.scrapValue)) + "\n";
		displayText += "____________________________\n\n";
		List<IGrouping<string, GrabbableObject>> list = (from item in source
			group item by item.itemProperties.itemName into @group
			orderby @group.Key
			select @group).ToList();
		string format3 = "{0} / x{1} / Total Value: ${2:F0}";
		string singleItem = "  {0} - Value: ${1:F0}";
		foreach (IGrouping<string, GrabbableObject> item in list)
		{
			displayText = displayText + string.Format(format3, item.Key, item.Count(), item.Sum((GrabbableObject item) => item.scrapValue)) + "\n";
			CollectionExtensions.Do<GrabbableObject>((IEnumerable<GrabbableObject>)item, (Action<GrabbableObject>)delegate(GrabbableObject item)
			{
				displayText = displayText + string.Format(singleItem, item.itemProperties.itemName, item.scrapValue) + "\n";
			});
			displayText += "\n";
		}
		return displayText;
	}
}
[HarmonyPatch(typeof(Terminal))]
[HarmonyPatch("RunTerminalEvents")]
public class RunTerminalEvents_Patch : MonoBehaviour
{
	private static IEnumerator PostfixCoroutine(Terminal __instance, TerminalNode node)
	{
		if (!string.IsNullOrWhiteSpace(node.terminalEvent) && !(node.terminalEvent != "stockoverview"))
		{
			node.displayText = StockOverview.BuildOverview();
		}
		yield break;
	}

	private static void Postfix(Terminal __instance, TerminalNode node)
	{
		((MonoBehaviour)__instance).StartCoroutine(PostfixCoroutine(__instance, node));
	}
}

BepInEx/plugins/PersistentPurchases/PersistentPurchases.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements.Collections;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PersistentPurchases")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Keeps bought ship objects after failing to meet quota")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("PersistentPurchases")]
[assembly: AssemblyTitle("PersistentPurchases")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PersistentPurchases
{
	[HarmonyPatch]
	public class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPriority(-23)]
		public static void generateConfig()
		{
			Plugin.setupConfig(StartOfRound.Instance.unlockablesList.unlockables);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		public static void storeUnlocked(StartOfRound __instance, out List<Tuple<int, Vector3, Vector3>> __state)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Plugin.log.LogInfo((object)"Taking note of bought unlockables");
			__state = new List<Tuple<int, Vector3, Vector3>>();
			List<UnlockableItem> unlockables = __instance.unlockablesList.unlockables;
			for (int i = 0; i < unlockables.Count; i++)
			{
				Plugin.log.LogDebug((object)$"{unlockables[i].unlockableName} - unlocked({unlockables[i].hasBeenUnlockedByPlayer}) - should persist({Plugin.unlockableConfig[i].Value})");
				if (unlockables[i].hasBeenUnlockedByPlayer && Plugin.unlockableConfig[i].Value)
				{
					__state.Add(Tuple.Create<int, Vector3, Vector3>(i, unlockables[i].placedPosition, unlockables[i].placedRotation));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		public static void loadUnlocked(StartOfRound __instance, List<Tuple<int, Vector3, Vector3>> __state)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			Plugin.log.LogInfo((object)"Rebuying unlockables");
			foreach (Tuple<int, Vector3, Vector3> item in __state)
			{
				Plugin.log.LogDebug((object)__instance.unlockablesList.unlockables[item.Item1].unlockableName);
				UnlockableItem val = __instance.unlockablesList.unlockables[item.Item1];
				__instance.BuyShipUnlockableServerRpc(item.Item1, TimeOfDay.Instance.quotaVariables.startingCredits);
				if (__instance.SpawnedShipUnlockables.ContainsKey(item.Item1))
				{
					NetworkObject component = DictionaryExtensions.Get<int, GameObject>((IDictionary<int, GameObject>)__instance.SpawnedShipUnlockables, item.Item1, (GameObject)null).GetComponent<NetworkObject>();
					if ((Object)(object)component != (Object)null)
					{
						ShipBuildModeManager.Instance.StoreObjectServerRpc(NetworkObjectReference.op_Implicit(component), 0);
					}
					else
					{
						Plugin.log.LogWarning((object)("Failed to find NetworkObject for " + val.unlockableName));
					}
				}
				else
				{
					Plugin.log.LogWarning((object)("SpawnedShipUnlockables did not contain " + val.unlockableName));
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
	public class RemoveUneccesaryAndAnnoyingReset
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			Plugin.log.LogInfo((object)"Beginning patching of GameNetworkManager.ResetSavedGameValues");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			bool flag = false;
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], typeof(GameNetworkManager).GetMethod("ResetUnlockablesListValues")))
				{
					flag = true;
					list[i - 1].opcode = OpCodes.Nop;
					list[i].opcode = OpCodes.Nop;
					list[i].operand = null;
					break;
				}
			}
			if (flag)
			{
				Plugin.log.LogInfo((object)"Patched GameNetworkManager.ResetSavedGameValues");
			}
			else
			{
				Plugin.log.LogError((object)"Failed to patch GameNetworkManager.ResetSavedGameValues!");
			}
			return list.AsEnumerable();
		}
	}
	[BepInPlugin("PersistentPurchases", "PersistentPurchases", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> placeUnlockables;

		public static ManualLogSource log = new ManualLogSource("PersistentPurchases");

		public static Harmony harmony = new Harmony("PersistentPurchases");

		public static string[] knownFurniture = new string[19]
		{
			"Cozy lights", "Television", "Cupboard", "File Cabinet", "Toilet", "Shower", "Light switch", "Record player", "Table", "Bunkbeds",
			"Terminal", "Romantic table", "JackOLantern", "Welcome mat", "Goldfish", "Plushie pajama man", "SmallRug", "LargeRug", "FatalitiesSign"
		};

		public static List<ConfigFile> despair = new List<ConfigFile>();

		public static List<ConfigEntry<bool>> unlockableConfig = new List<ConfigEntry<bool>>();

		private void Awake()
		{
			Logger.Sources.Add((ILogSource)(object)log);
			despair.Add(((BaseUnityPlugin)this).Config);
			harmony.PatchAll(typeof(Patches));
			harmony.PatchAll(typeof(RemoveUneccesaryAndAnnoyingReset));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin PersistentPurchases is loaded!");
		}

		public static void setupConfig(List<UnlockableItem> unlockables)
		{
			log.LogInfo((object)$"Registering {unlockables.Count} unlockables");
			for (int i = 0; i < unlockables.Count; i++)
			{
				log.LogDebug((object)(unlockables[i].unlockableName ?? ""));
				unlockableConfig.Add(despair[0].Bind<bool>("Unlockables", unlockables[i].unlockableName, unlockables[i].unlockableType == 0 || knownFurniture.Contains(unlockables[i].unlockableName), (ConfigDescription)null));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PersistentPurchases";

		public const string PLUGIN_NAME = "PersistentPurchases";

		public const string PLUGIN_VERSION = "1.1.1";
	}
}

BepInEx/plugins/TerminalApi.dll

Decompiled 8 months 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using TerminalApi.Classes;
using TerminalApi.Interfaces;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("NotAtomicBomb")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Terminal Api for the terminal in Lethal Company")]
[assembly: AssemblyFileVersion("1.5.1.0")]
[assembly: AssemblyInformationalVersion("1.5.1+9b12d17b39fe1f9518b55effc9f9d6af53ea5e0d")]
[assembly: AssemblyProduct("TerminalApi")]
[assembly: AssemblyTitle("TerminalApi")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/NotAtomicBomb/TerminalApi")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TerminalApi
{
	internal class DelayedAddTerminalKeyword : IDelayedAction
	{
		internal Action<TerminalKeyword, CommandInfo> Action { get; set; }

		internal CommandInfo CommandInfo { get; set; }

		internal TerminalKeyword Keyword { get; set; }

		public void Run()
		{
			Action(Keyword, CommandInfo);
		}
	}
	[BepInPlugin("atomic.terminalapi", "Terminal Api", "1.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> configEnableLogs;

		public ManualLogSource Log;

		internal void SetupConfig()
		{
			configEnableLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "enableLogs", true, "Whether or not to display logs pertaining to TerminalAPI. Will still log that the mod has loaded.");
		}

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			SetupConfig();
			object obj = this;
			obj = (object)((!configEnableLogs.Value) ? ((ManualLogSource)null) : new ManualLogSource("Terminal Api"));
			((Plugin)obj).Log = (ManualLogSource)obj;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin TerminalApi is loaded!");
			if (Log != null)
			{
				Logger.Sources.Add((ILogSource)(object)Log);
			}
			TerminalApi.plugin = this;
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}
	public static class TerminalApi
	{
		public static Plugin plugin;

		internal static List<IDelayedAction> QueuedDelayedActions = new List<IDelayedAction>();

		internal static List<CommandInfo> CommandInfos = new List<CommandInfo>();

		public static Terminal Terminal { get; internal set; }

		public static List<TerminalNode> SpecialNodes => Terminal.terminalNodes.specialNodes;

		public static string CurrentText => Terminal.currentText;

		public static TMP_InputField ScreenText => Terminal.screenText;

		public static bool IsInGame()
		{
			try
			{
				return Terminal != null;
			}
			catch (NullReferenceException)
			{
				return false;
			}
		}

		public static void AddCommand(string commandWord, string displayText, string verbWord = null, bool clearPreviousText = true)
		{
			commandWord = commandWord.ToLower();
			TerminalKeyword val = CreateTerminalKeyword(commandWord);
			TerminalNode val2 = CreateTerminalNode(displayText, clearPreviousText);
			if (verbWord != null)
			{
				verbWord = verbWord.ToLower();
				TerminalKeyword terminalKeyword = CreateTerminalKeyword(verbWord, isVerb: true);
				AddTerminalKeyword(val.defaultVerb = terminalKeyword.AddCompatibleNoun(val, val2));
				AddTerminalKeyword(val);
			}
			else
			{
				val.specialKeywordResult = val2;
				AddTerminalKeyword(val);
			}
		}

		public static void AddCommand(string commandWord, CommandInfo commandInfo, string verbWord = null, bool clearPreviousText = true)
		{
			commandWord = commandWord.ToLower();
			TerminalKeyword val = CreateTerminalKeyword(commandWord);
			TerminalNode val3 = (commandInfo.TriggerNode = CreateTerminalNode("", clearPreviousText));
			if (verbWord != null)
			{
				verbWord = verbWord.ToLower();
				TerminalKeyword terminalKeyword = CreateTerminalKeyword(verbWord, isVerb: true);
				AddTerminalKeyword(val.defaultVerb = terminalKeyword.AddCompatibleNoun(val, val3));
				AddTerminalKeyword(val, commandInfo);
			}
			else
			{
				val.specialKeywordResult = val3;
				AddTerminalKeyword(val, commandInfo);
			}
		}

		public static TerminalKeyword CreateTerminalKeyword(string word, bool isVerb = false, TerminalNode triggeringNode = null)
		{
			TerminalKeyword obj = ScriptableObject.CreateInstance<TerminalKeyword>();
			obj.word = word.ToLower();
			obj.isVerb = isVerb;
			obj.specialKeywordResult = triggeringNode;
			return obj;
		}

		public static TerminalKeyword CreateTerminalKeyword(string word, string displayText, bool clearPreviousText = false, string terminalEvent = "")
		{
			TerminalKeyword obj = ScriptableObject.CreateInstance<TerminalKeyword>();
			obj.word = word.ToLower();
			obj.isVerb = false;
			obj.specialKeywordResult = CreateTerminalNode(displayText, clearPreviousText, terminalEvent);
			return obj;
		}

		public static TerminalNode CreateTerminalNode(string displayText, bool clearPreviousText = false, string terminalEvent = "")
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.displayText = displayText;
			obj.clearPreviousText = clearPreviousText;
			obj.terminalEvent = terminalEvent;
			return obj;
		}

		public static void AddTerminalKeyword(TerminalKeyword terminalKeyword)
		{
			if (IsInGame())
			{
				if (GetKeyword(terminalKeyword.word) == null)
				{
					Terminal.terminalNodes.allKeywords = Terminal.terminalNodes.allKeywords.Add(terminalKeyword);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("Added " + terminalKeyword.word + " keyword to terminal keywords."));
					}
				}
				else
				{
					ManualLogSource log2 = plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Failed to add " + terminalKeyword.word + " keyword. Already exists."));
					}
				}
			}
			else
			{
				ManualLogSource log3 = plugin.Log;
				if (log3 != null)
				{
					log3.LogMessage((object)("Not in game, waiting to be in game to add " + terminalKeyword.word + " keyword."));
				}
				Action<TerminalKeyword, CommandInfo> action = AddTerminalKeyword;
				DelayedAddTerminalKeyword item = new DelayedAddTerminalKeyword
				{
					Action = action,
					Keyword = terminalKeyword
				};
				QueuedDelayedActions.Add(item);
			}
		}

		public static void AddTerminalKeyword(TerminalKeyword terminalKeyword, CommandInfo commandInfo = null)
		{
			if (IsInGame())
			{
				if (GetKeyword(terminalKeyword.word) == null)
				{
					if (commandInfo?.DisplayTextSupplier != null)
					{
						if (commandInfo?.TriggerNode == null)
						{
							commandInfo.TriggerNode = terminalKeyword.specialKeywordResult;
						}
						CommandInfos.Add(commandInfo);
					}
					if (commandInfo != null)
					{
						((Object)terminalKeyword).name = commandInfo.Title ?? (terminalKeyword.word.Substring(0, 1).ToUpper() + terminalKeyword.word.Substring(1));
						string text = "\n>" + ((Object)terminalKeyword).name.ToUpper() + "\n" + commandInfo.Description + "\n\n";
						NodeAppendLine(commandInfo.Category, text);
					}
					Terminal.terminalNodes.allKeywords = Terminal.terminalNodes.allKeywords.Add(terminalKeyword);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("Added " + terminalKeyword.word + " keyword to terminal keywords."));
					}
				}
				else
				{
					ManualLogSource log2 = plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Failed to add " + terminalKeyword.word + " keyword. Already exists."));
					}
				}
			}
			else
			{
				ManualLogSource log3 = plugin.Log;
				if (log3 != null)
				{
					log3.LogMessage((object)("Not in game, waiting to be in game to add " + terminalKeyword.word + " keyword."));
				}
				Action<TerminalKeyword, CommandInfo> action = AddTerminalKeyword;
				DelayedAddTerminalKeyword item = new DelayedAddTerminalKeyword
				{
					Action = action,
					Keyword = terminalKeyword,
					CommandInfo = commandInfo
				};
				QueuedDelayedActions.Add(item);
			}
		}

		public static void NodeAppendLine(string word, string text)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(word.ToLower());
			if ((Object)(object)keyword != (Object)null)
			{
				keyword.specialKeywordResult.displayText = keyword.specialKeywordResult.displayText.Trim() + "\n" + text;
				return;
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Failed to add text to " + word + ". Does not exist."));
			}
		}

		public static TerminalKeyword GetKeyword(string keyword)
		{
			if (IsInGame())
			{
				return ((IEnumerable<TerminalKeyword>)Terminal.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword Kw) => Kw.word == keyword));
			}
			return null;
		}

		public static void UpdateKeyword(TerminalKeyword keyword)
		{
			if (!IsInGame())
			{
				return;
			}
			for (int i = 0; i < Terminal.terminalNodes.allKeywords.Length; i++)
			{
				if (Terminal.terminalNodes.allKeywords[i].word == keyword.word)
				{
					Terminal.terminalNodes.allKeywords[i] = keyword;
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Failed to update " + keyword.word + ". Was not found in keywords."));
			}
		}

		public static void DeleteKeyword(string word)
		{
			if (!IsInGame())
			{
				return;
			}
			for (int i = 0; i < Terminal.terminalNodes.allKeywords.Length; i++)
			{
				if (Terminal.terminalNodes.allKeywords[i].word == word.ToLower())
				{
					int newSize = Terminal.terminalNodes.allKeywords.Length - 1;
					for (int j = i + 1; j < Terminal.terminalNodes.allKeywords.Length; j++)
					{
						Terminal.terminalNodes.allKeywords[j - 1] = Terminal.terminalNodes.allKeywords[j];
					}
					Array.Resize(ref Terminal.terminalNodes.allKeywords, newSize);
					ManualLogSource log = plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)(word + " was deleted successfully."));
					}
					return;
				}
			}
			ManualLogSource log2 = plugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("Failed to delete " + word + ". Was not found in keywords."));
			}
		}

		public static void UpdateKeywordCompatibleNoun(TerminalKeyword verbKeyword, string noun, TerminalNode newTriggerNode)
		{
			if (!IsInGame() || !verbKeyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < verbKeyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = verbKeyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result = newTriggerNode;
					UpdateKeyword(verbKeyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {verbKeyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(string verbWord, string noun, TerminalNode newTriggerNode)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			if (!keyword.isVerb || verbWord == null)
			{
				return;
			}
			for (int i = 0; i < keyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = keyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result = newTriggerNode;
					UpdateKeyword(keyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {keyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(TerminalKeyword verbKeyword, string noun, string newDisplayText)
		{
			if (!IsInGame() || !verbKeyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < verbKeyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = verbKeyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result.displayText = newDisplayText;
					UpdateKeyword(verbKeyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {verbKeyword}");
			}
		}

		public static void UpdateKeywordCompatibleNoun(string verbWord, string noun, string newDisplayText)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			if (!keyword.isVerb)
			{
				return;
			}
			for (int i = 0; i < keyword.compatibleNouns.Length; i++)
			{
				CompatibleNoun val = keyword.compatibleNouns[i];
				if (val.noun.word == noun)
				{
					val.result.displayText = newDisplayText;
					UpdateKeyword(keyword);
					return;
				}
			}
			ManualLogSource log = plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"WARNING: No noun found for {keyword}");
			}
		}

		public static void AddCompatibleNoun(TerminalKeyword verbKeyword, string noun, string displayText, bool clearPreviousText = false)
		{
			if (IsInGame())
			{
				TerminalKeyword keyword = GetKeyword(noun);
				verbKeyword = verbKeyword.AddCompatibleNoun(keyword, displayText, clearPreviousText);
				UpdateKeyword(verbKeyword);
			}
		}

		public static void AddCompatibleNoun(TerminalKeyword verbKeyword, string noun, TerminalNode triggerNode)
		{
			if (IsInGame())
			{
				TerminalKeyword keyword = GetKeyword(noun);
				verbKeyword = verbKeyword.AddCompatibleNoun(keyword, triggerNode);
				UpdateKeyword(verbKeyword);
			}
		}

		public static void AddCompatibleNoun(string verbWord, string noun, TerminalNode triggerNode)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			TerminalKeyword keyword2 = GetKeyword(noun);
			if ((Object)(object)keyword == (Object)null)
			{
				ManualLogSource log = plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"The verb given does not exist.");
				}
			}
			else
			{
				keyword = keyword.AddCompatibleNoun(keyword2, triggerNode);
				UpdateKeyword(keyword);
			}
		}

		public static void AddCompatibleNoun(string verbWord, string noun, string displayText, bool clearPreviousText = false)
		{
			if (!IsInGame())
			{
				return;
			}
			TerminalKeyword keyword = GetKeyword(verbWord);
			TerminalKeyword keyword2 = GetKeyword(noun);
			if ((Object)(object)keyword == (Object)null)
			{
				ManualLogSource log = plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"The verb given does not exist.");
				}
			}
			else
			{
				keyword = keyword.AddCompatibleNoun(keyword2, displayText, clearPreviousText);
				UpdateKeyword(keyword);
			}
		}

		public static string GetTerminalInput()
		{
			if (IsInGame())
			{
				return CurrentText.Substring(CurrentText.Length - Terminal.textAdded);
			}
			return "";
		}

		public static void SetTerminalInput(string terminalInput)
		{
			Terminal.TextChanged(CurrentText.Substring(0, CurrentText.Length - Terminal.textAdded) + terminalInput);
			ScreenText.text = CurrentText;
			Terminal.textAdded = terminalInput.Length;
		}
	}
	public static class TerminalExtenstionMethods
	{
		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword noun, TerminalNode result)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = noun,
					result = result
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, string noun, TerminalNode result)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = TerminalApi.CreateTerminalKeyword(noun),
					result = result
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, string noun, string displayText)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = TerminalApi.CreateTerminalKeyword(noun),
					result = TerminalApi.CreateTerminalNode(displayText)
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		public static TerminalKeyword AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword noun, string displayText, bool clearPreviousText = false)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (terminalKeyword.isVerb)
			{
				CompatibleNoun val = new CompatibleNoun
				{
					noun = noun,
					result = TerminalApi.CreateTerminalNode(displayText, clearPreviousText)
				};
				if (terminalKeyword.compatibleNouns == null)
				{
					terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[1] { val };
				}
				else
				{
					terminalKeyword.compatibleNouns = terminalKeyword.compatibleNouns.Add(val);
				}
				return terminalKeyword;
			}
			return null;
		}

		internal static T[] Add<T>(this T[] array, T newItem)
		{
			int num = array.Length + 1;
			Array.Resize(ref array, num);
			array[num - 1] = newItem;
			return array;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TerminalApi";

		public const string PLUGIN_NAME = "TerminalApi";

		public const string PLUGIN_VERSION = "1.5.1";
	}
}
namespace TerminalApi.Interfaces
{
	internal interface IDelayedAction
	{
		internal void Run();
	}
}
namespace TerminalApi.Events
{
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyPatch(typeof(Terminal))]
	public static class Events
	{
		public class TerminalEventArgs : EventArgs
		{
			public Terminal Terminal { get; set; }
		}

		public delegate void TerminalEventHandler(object sender, TerminalEventArgs e);

		public class TerminalParseSentenceEventArgs : TerminalEventArgs
		{
			public TerminalNode ReturnedNode { get; set; }

			public string SubmittedText { get; set; }
		}

		public delegate void TerminalParseSentenceEventHandler(object sender, TerminalParseSentenceEventArgs e);

		public class TerminalTextChangedEventArgs : TerminalEventArgs
		{
			public string NewText;

			public string CurrentInputText;
		}

		public delegate void TerminalTextChangedEventHandler(object sender, TerminalTextChangedEventArgs e);

		public static event TerminalEventHandler TerminalAwake;

		public static event TerminalEventHandler TerminalWaking;

		public static event TerminalEventHandler TerminalStarted;

		public static event TerminalEventHandler TerminalStarting;

		public static event TerminalEventHandler TerminalBeginUsing;

		public static event TerminalEventHandler TerminalBeganUsing;

		public static event TerminalEventHandler TerminalExited;

		public static event TerminalParseSentenceEventHandler TerminalParsedSentence;

		public static event TerminalTextChangedEventHandler TerminalTextChanged;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake(ref Terminal __instance)
		{
			TerminalApi.Terminal = __instance;
			if (TerminalApi.QueuedDelayedActions.Count > 0)
			{
				ManualLogSource log = TerminalApi.plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)"In game, applying any changes now.");
				}
				foreach (IDelayedAction queuedDelayedAction in TerminalApi.QueuedDelayedActions)
				{
					queuedDelayedAction.Run();
				}
				TerminalApi.QueuedDelayedActions.Clear();
			}
			Events.TerminalAwake?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("BeginUsingTerminal")]
		[HarmonyPostfix]
		public static void BeganUsing(ref Terminal __instance)
		{
			Events.TerminalBeganUsing?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("QuitTerminal")]
		[HarmonyPostfix]
		public static void OnQuitTerminal(ref Terminal __instance)
		{
			Events.TerminalExited?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("BeginUsingTerminal")]
		[HarmonyPrefix]
		public static void OnBeginUsing(ref Terminal __instance)
		{
			Events.TerminalBeginUsing?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		public static void ParsePlayerSentence(ref Terminal __instance, TerminalNode __result)
		{
			CommandInfo commandInfo = TerminalApi.CommandInfos.FirstOrDefault((CommandInfo cI) => (Object)(object)cI.TriggerNode == (Object)(object)__result);
			if (commandInfo != null)
			{
				__result.displayText = commandInfo?.DisplayTextSupplier();
			}
			string submittedText = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
			Events.TerminalParsedSentence?.Invoke(__instance, new TerminalParseSentenceEventArgs
			{
				Terminal = __instance,
				SubmittedText = submittedText,
				ReturnedNode = __result
			});
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Started(ref Terminal __instance)
		{
			Events.TerminalStarted?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void Starting(ref Terminal __instance)
		{
			Events.TerminalStarting?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}

		[HarmonyPatch("TextChanged")]
		[HarmonyPostfix]
		public static void OnTextChanged(ref Terminal __instance, string newText)
		{
			string currentInputText = "";
			if (newText.Trim().Length >= __instance.textAdded)
			{
				currentInputText = newText.Substring(newText.Length - __instance.textAdded);
			}
			Events.TerminalTextChanged?.Invoke(__instance, new TerminalTextChangedEventArgs
			{
				Terminal = __instance,
				NewText = newText,
				CurrentInputText = currentInputText
			});
		}

		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void Waking(ref Terminal __instance)
		{
			Events.TerminalWaking?.Invoke(__instance, new TerminalEventArgs
			{
				Terminal = __instance
			});
		}
	}
}
namespace TerminalApi.Classes
{
	public class CommandInfo
	{
		public string Title { get; set; }

		public string Category { get; set; }

		public string Description { get; set; }

		public TerminalNode TriggerNode { get; set; }

		public Func<string> DisplayTextSupplier { get; set; }
	}
}

BepInEx/Plugins/LetMeLookDown.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using GameNetcodeStuff;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LetMeLookDown")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LetMeLookDown")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a9c88d54-8f01-44a7-be0d-bd61d38aadcb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LetMeLookDown
{
	[BepInPlugin("FlipMods.LetMeLookDown", "LetMeLookDown", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private static Plugin instance;

		public static float maxAngle = 80f;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			_harmony = new Harmony("LetMeLookDown");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LetMeLookDown mod loaded");
			instance = this;
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.LetMeLookDown";

		public const string PLUGIN_NAME = "LetMeLookDown";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace LetMeLookDown.Patches
{
	[HarmonyPatch]
	internal class AdjustSmoothLookingPatcher
	{
		[HarmonyPatch(typeof(PlayerControllerB), "CalculateSmoothLookingInput")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 60f)
				{
					list[i].operand = Plugin.maxAngle;
					break;
				}
			}
			return list.AsEnumerable();
		}
	}
	[HarmonyPatch]
	internal class AdjustNormalLookingPatcher
	{
		[HarmonyPatch(typeof(PlayerControllerB), "CalculateNormalLookingInput")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 60f)
				{
					list[i].operand = Plugin.maxAngle;
					break;
				}
			}
			return list.AsEnumerable();
		}
	}
}

BepInEx/plugins/DevysOQLMod.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using DevysOQLMod.Patches;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DevysOQLMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DevysOQLMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5a1bb5c9-fe79-4f4a-9abe-ae396f0f481f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DevysOQLMod
{
	[BepInPlugin("Devy.QuailtyOfLifeMod", "Devy's OQL Mod", "1.0.0")]
	public class DevysOQLModBase : BaseUnityPlugin
	{
		private const string modGUID = "Devy.QuailtyOfLifeMod";

		private const string modName = "Devy's OQL Mod";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Devy.QuailtyOfLifeMod");

		private static DevysOQLModBase Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("Devy.QuailtyOfLifeMod");
			mls.LogInfo((object)"Devy's Mod awakon");
			harmony.PatchAll(typeof(DevysOQLModBase));
			harmony.PatchAll(typeof(InverseTeleporterPatch));
			harmony.PatchAll();
		}
	}
}
namespace DevysOQLMod.Patches
{
	[HarmonyPatch(typeof(ShipTeleporter))]
	internal class InverseTeleporterPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static void noCooldown(ref float ___cooldownAmount)
		{
			___cooldownAmount = 10f;
		}
	}
}

BepInEx/plugins/BetterInverseTeleporter.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetterInverseTeleporter")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Take your items with you while teleporting into the facility.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2931884825f83dc2ab8f3c8bc51e5d16263afaff")]
[assembly: AssemblyProduct("BetterInverseTeleporter")]
[assembly: AssemblyTitle("BetterInverseTeleporter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace bit
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "BetterInverseTeleporter";

		public const string PLUGIN_NAME = "BetterInverseTeleporter";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Bit
{
	[BepInPlugin("portable-navi.bit", "BetterInverseTeleporter", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string mod_name = "BetterInverseTeleporter";

		public const string mod_guid = "portable-navi.bit";

		public const string mod_version = "1.0.0";

		private readonly Harmony _patcher = new Harmony("portable-navi.bit");

		private static Plugin _instance;

		private ManualLogSource _log;

		public static Plugin instance => _instance;

		public Harmony patcher => _patcher;

		public ManualLogSource log => _log;

		private void Awake()
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = this;
			}
			_log = Logger.CreateLogSource("portable-navi.bit");
			_patcher.PatchAll();
			log.LogInfo((object)"Patch applied!");
		}
	}
}
namespace Bit.patches
{
	[HarmonyPatch]
	internal class Bit
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ShipTeleporter), "TeleportPlayerOutWithInverseTeleporter")]
		public static bool teleport(int playerObj, ref Vector3 teleportPos, ShipTeleporter __instance)
		{
			//IL_005a: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo method = typeof(ShipTeleporter).GetMethod("teleportBodyOut", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method2 = typeof(ShipTeleporter).GetMethod("SetPlayerTeleporterId", BindingFlags.Instance | BindingFlags.NonPublic);
			if (StartOfRound.Instance.allPlayerScripts[playerObj].isPlayerDead)
			{
				((MonoBehaviour)__instance).StartCoroutine((IEnumerator)method.Invoke(__instance, new object[2] { playerObj, teleportPos }));
				return false;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerObj];
			method2.Invoke(__instance, new object[2] { val, -1 });
			if (Object.op_Implicit((Object)(object)Object.FindObjectOfType<AudioReverbPresets>()))
			{
				Object.FindObjectOfType<AudioReverbPresets>().audioPresets[2].ChangeAudioReverbForPlayer(val);
			}
			val.isInElevator = false;
			val.isInHangarShipRoom = false;
			val.isInsideFactory = true;
			val.averageVelocity = 0f;
			val.velocityLastFrame = Vector3.zero;
			StartOfRound.Instance.allPlayerScripts[playerObj].TeleportPlayer(teleportPos, false, 0f, false, true);
			StartOfRound.Instance.allPlayerScripts[playerObj].beamOutParticle.Play();
			__instance.shipTeleporterAudio.PlayOneShot(__instance.teleporterBeamUpSFX);
			StartOfRound.Instance.allPlayerScripts[playerObj].movementAudio.PlayOneShot(__instance.teleporterBeamUpSFX);
			if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
			return false;
		}
	}
}

BepInEx/plugins/LethalCompanyInputUtils.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalCompanyInputUtils.Data;
using LethalCompanyInputUtils.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[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("LethalCompanyInputUtils")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0a3dbf237fa80a6f3ddd4184ede68dc95465ebd1")]
[assembly: AssemblyProduct("LethalCompanyInputUtils")]
[assembly: AssemblyTitle("LethalCompanyInputUtils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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 LethalCompanyInputUtils
{
	public static class LcInputActionApi
	{
		private static readonly Dictionary<string, LcInputActions> InputActionsMap = new Dictionary<string, LcInputActions>();

		private static IReadOnlyCollection<LcInputActions> InputActions => InputActionsMap.Values;

		internal static void LoadIntoUI(KepRemapPanel panel)
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00e0: Expected O, but got Unknown
			List<RemappableKey> remappableKeys = panel.remappableKeys;
			int num = remappableKeys.Count((RemappableKey key) => !key.gamepadOnly);
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Loaded)
				{
					continue;
				}
				foreach (InputActionReference actionRef in inputAction.ActionRefs)
				{
					InputBinding val = ((IEnumerable<InputBinding>)(object)actionRef.action.bindings).First();
					string name = ((InputBinding)(ref val)).name;
					RemappableKey item = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						gamepadOnly = false
					};
					remappableKeys.Insert(num++, item);
					RemappableKey item2 = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						rebindingIndex = 1,
						gamepadOnly = true
					};
					remappableKeys.Add(item2);
				}
				inputAction.Loaded = true;
			}
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
		}

		internal static void CalculateVerticalMaxForGamepad(KepRemapPanel panel)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			int num = panel.remappableKeys.Count((RemappableKey key) => key.gamepadOnly);
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
		}

		internal static void ResetLoadedInputActions()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Loaded = false;
			}
		}

		internal static void RegisterInputActions(LcInputActions lcInputActions, InputActionMapBuilder builder)
		{
			if (!InputActionsMap.TryAdd(lcInputActions.Id, lcInputActions))
			{
				Logging.Logger.LogWarning((object)("The mod [" + lcInputActions.Plugin.GUID + "] instantiated an Actions class [" + lcInputActions.GetType().Name + "] more than once!\n\t These classes should be treated as singletons!, do not instantiate more than once!"));
			}
			else
			{
				lcInputActions.CreateInputActions(in builder);
				InputActionSetupExtensions.AddActionMap(lcInputActions.GetAsset(), builder.Build());
				lcInputActions.GetAsset().Enable();
				lcInputActions.OnAssetLoaded();
				lcInputActions.Load();
				lcInputActions.BuildActionRefs();
			}
		}

		internal static void DisableForRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Enabled)
				{
					inputAction.Disable();
				}
			}
		}

		internal static void ReEnableFromRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.WasEnabled)
				{
					inputAction.Enable();
				}
			}
		}

		internal static void SaveOverrides()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Save();
			}
		}
	}
	[BepInPlugin("com.rune580.LethalCompanyInputUtils", "Lethal Company Input Utils", "0.4.2")]
	public class LethalCompanyInputUtilsPlugin : BaseUnityPlugin
	{
		public const string ModId = "com.rune580.LethalCompanyInputUtils";

		public const string ModName = "Lethal Company Input Utils";

		public const string ModVersion = "0.4.2";

		private Harmony? _harmony;

		private void Awake()
		{
			Logging.SetLogSource(((BaseUnityPlugin)this).Logger);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.rune580.LethalCompanyInputUtils");
			SceneManager.activeSceneChanged += OnSceneChanged;
			FsUtils.EnsureControlsDir();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.rune580.LethalCompanyInputUtils is loaded!");
		}

		private static void OnSceneChanged(Scene current, Scene next)
		{
			LcInputActionApi.ResetLoadedInputActions();
		}
	}
}
namespace LethalCompanyInputUtils.Utils
{
	internal static class AssemblyUtils
	{
		public static BepInPlugin? GetBepInPlugin(this Assembly assembly)
		{
			Type[] exportedTypes = assembly.GetExportedTypes();
			for (int i = 0; i < exportedTypes.Length; i++)
			{
				BepInPlugin customAttribute = ((MemberInfo)exportedTypes[i]).GetCustomAttribute<BepInPlugin>();
				if (customAttribute != null)
				{
					return customAttribute;
				}
			}
			return null;
		}
	}
	internal static class FsUtils
	{
		public static string SaveDir { get; } = GetSaveDir();


		public static string Pre041ControlsDir { get; } = Path.Combine(Paths.BepInExRootPath, "controls");


		public static string ControlsDir { get; } = Path.Combine(Paths.ConfigPath, "controls");


		private static string GetSaveDir()
		{
			string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
			return Path.Combine(folderPath, "AppData", "LocalLow", "ZeekerssRBLX", "Lethal Company");
		}

		public static void EnsureControlsDir()
		{
			if (!Directory.Exists(ControlsDir))
			{
				Directory.CreateDirectory(ControlsDir);
			}
		}
	}
	internal static class Logging
	{
		private static ManualLogSource? _logSource;

		internal static ManualLogSource Logger { get; } = _logSource;


		internal static void SetLogSource(ManualLogSource logSource)
		{
			_logSource = logSource;
		}
	}
}
namespace LethalCompanyInputUtils.Patches
{
	public static class KeyRemapPanelPatches
	{
		[HarmonyPatch(typeof(KepRemapPanel), "LoadKeybindsUI")]
		public static class LoadKeybindsUIPatch
		{
			public static void Prefix(KepRemapPanel __instance)
			{
				LcInputActionApi.DisableForRebind();
				LcInputActionApi.LoadIntoUI(__instance);
			}

			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Expected O, but got Unknown
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Expected O, but got Unknown
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Expected O, but got Unknown
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Expected O, but got Unknown
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				FieldInfo maxVerticalField = AccessTools.Field(typeof(KepRemapPanel), "maxVertical");
				val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsLdarg(code, (int?)0)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.LoadsField(code, maxVerticalField, false)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 2f), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Add), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Conv_I4), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null)), (string)null)
				});
				val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LcInputActionApi), "CalculateVerticalMaxForGamepad", new Type[1] { typeof(KepRemapPanel) }, (Type[])null))
				});
				return val.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(KepRemapPanel), "UnloadKeybindsUI")]
		public static class UnloadKeybindsUIPatch
		{
			public static void Prefix()
			{
				LcInputActionApi.SaveOverrides();
				LcInputActionApi.ReEnableFromRebind();
			}
		}
	}
}
namespace LethalCompanyInputUtils.Data
{
	[Serializable]
	public struct BindingOverride
	{
		public string? action;

		public string? origPath;

		public string? path;
	}
	[Serializable]
	public class BindingOverrides
	{
		public List<BindingOverride> overrides;

		private BindingOverrides()
		{
			overrides = new List<BindingOverride>();
		}

		public BindingOverrides(IEnumerable<InputBinding> bindings)
		{
			//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)
			overrides = new List<BindingOverride>();
			foreach (InputBinding binding in bindings)
			{
				InputBinding current = binding;
				if (((InputBinding)(ref current)).hasOverrides)
				{
					BindingOverride item = new BindingOverride
					{
						action = ((InputBinding)(ref current)).action,
						origPath = ((InputBinding)(ref current)).path,
						path = ((InputBinding)(ref current)).overridePath
					};
					overrides.Add(item);
				}
			}
		}

		public void LoadInto(InputActionAsset asset)
		{
			foreach (BindingOverride @override in overrides)
			{
				InputAction obj = asset.FindAction(@override.action, false);
				if (obj != null)
				{
					InputActionRebindingExtensions.ApplyBindingOverride(obj, @override.path, (string)null, @override.origPath);
				}
			}
		}

		public static BindingOverrides FromJson(string json)
		{
			BindingOverrides bindingOverrides = new BindingOverrides();
			JToken value = JsonConvert.DeserializeObject<JObject>(json).GetValue("overrides");
			bindingOverrides.overrides = value.ToObject<List<BindingOverride>>();
			return bindingOverrides;
		}
	}
}
namespace LethalCompanyInputUtils.Api
{
	[AttributeUsage(AttributeTargets.Property)]
	public class InputActionAttribute : Attribute
	{
		public readonly string KbmPath;

		public string? ActionId { get; set; }

		public string? GamepadPath { get; set; }

		public InputActionType ActionType { get; set; } = (InputActionType)1;


		public string? KbmInteractions { get; set; }

		public string? GamepadInteractions { get; set; }

		public string? Name { get; set; }

		[Obsolete("Prefer using the named optional params instead.")]
		public InputActionAttribute(string action, string kbmPath, string gamepadPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ActionId = action;
			KbmPath = kbmPath;
			GamepadPath = gamepadPath;
		}

		public InputActionAttribute(string kbmPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			KbmPath = kbmPath;
		}
	}
	public class InputActionBindingBuilder
	{
		private readonly InputActionMapBuilder _mapBuilder;

		private string? _actionId;

		private string? _kbmPath;

		private string? _gamepadPath;

		private string? _kbmInteractions;

		private string? _gamepadInteractions;

		private InputActionType _actionType;

		private string? _name;

		internal InputActionBindingBuilder(InputActionMapBuilder mapBuilder)
		{
			_mapBuilder = mapBuilder;
		}

		public InputActionBindingBuilder WithActionId(string actionId)
		{
			_actionId = actionId;
			return this;
		}

		public InputActionBindingBuilder WithKbmPath(string kbmPath)
		{
			_kbmPath = kbmPath;
			return this;
		}

		public InputActionBindingBuilder WithGamepadPath(string gamepadPath)
		{
			_gamepadPath = gamepadPath;
			return this;
		}

		public InputActionBindingBuilder WithKbmInteractions(string? kbmInteractions)
		{
			_kbmInteractions = kbmInteractions;
			return this;
		}

		public InputActionBindingBuilder WithGamepadInteractions(string? gamepadInteractions)
		{
			_gamepadInteractions = gamepadInteractions;
			return this;
		}

		public InputActionBindingBuilder WithActionType(InputActionType actionType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_actionType = actionType;
			return this;
		}

		public InputActionBindingBuilder WithBindingName(string? name)
		{
			_name = name;
			return this;
		}

		public InputAction Finish()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (_name == null)
			{
				_name = _actionId;
			}
			InputAction val = new InputAction(_actionId, _actionType, (string)null, (string)null, (string)null, (string)null);
			_mapBuilder.WithAction(val);
			if (_kbmPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_kbmPath, _actionId, (string)null, (string)null, _kbmInteractions, _name));
			}
			if (_gamepadPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_gamepadPath, _actionId, (string)null, (string)null, _gamepadInteractions, _name));
			}
			return val;
		}
	}
	public class InputActionMapBuilder
	{
		private readonly InputActionMap _actionMap = new InputActionMap(mapName);

		public InputActionMapBuilder(string mapName)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown


		public InputActionMapBuilder WithAction(InputAction action)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddAction(_actionMap, action.name, action.type, (string)null, (string)null, (string)null, (string)null, (string)null);
			return this;
		}

		public InputActionMapBuilder WithBinding(InputBinding binding)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddBinding(_actionMap, binding);
			return this;
		}

		public InputActionBindingBuilder NewActionBinding()
		{
			return new InputActionBindingBuilder(this);
		}

		internal InputActionMap Build()
		{
			return _actionMap;
		}
	}
	public abstract class LcInputActions
	{
		private readonly string _jsonPath;

		private readonly List<InputActionReference> _actionRefs = new List<InputActionReference>();

		protected readonly InputActionAsset Asset;

		internal bool Loaded;

		private readonly Dictionary<PropertyInfo, InputActionAttribute> _inputProps;

		internal bool WasEnabled { get; private set; }

		public bool Enabled => Asset.enabled;

		internal IReadOnlyCollection<InputActionReference> ActionRefs => _actionRefs;

		internal string Id => Plugin.GUID + "." + MapName;

		public BepInPlugin Plugin { get; }

		protected virtual string MapName => GetType().Name;

		internal InputActionAsset GetAsset()
		{
			return Asset;
		}

		protected LcInputActions()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			Asset = ScriptableObject.CreateInstance<InputActionAsset>();
			Plugin = Assembly.GetCallingAssembly().GetBepInPlugin() ?? throw new InvalidOperationException();
			_jsonPath = Path.Combine(FsUtils.ControlsDir, Id + ".json");
			InputActionMapBuilder inputActionMapBuilder = new InputActionMapBuilder(Id);
			PropertyInfo[] properties = GetType().GetProperties();
			_inputProps = new Dictionary<PropertyInfo, InputActionAttribute>();
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				InputActionAttribute customAttribute = propertyInfo.GetCustomAttribute<InputActionAttribute>();
				if (customAttribute != null && !(propertyInfo.PropertyType != typeof(InputAction)))
				{
					InputActionAttribute inputActionAttribute = customAttribute;
					if (inputActionAttribute.ActionId == null)
					{
						string text = (inputActionAttribute.ActionId = propertyInfo.Name);
					}
					inputActionAttribute = customAttribute;
					if (inputActionAttribute.GamepadPath == null)
					{
						string text = (inputActionAttribute.GamepadPath = "");
					}
					inputActionMapBuilder.NewActionBinding().WithActionId(customAttribute.ActionId).WithActionType(customAttribute.ActionType)
						.WithBindingName(customAttribute.Name)
						.WithKbmPath(customAttribute.KbmPath)
						.WithGamepadPath(customAttribute.GamepadPath)
						.WithKbmInteractions(customAttribute.KbmInteractions)
						.WithGamepadInteractions(customAttribute.GamepadInteractions)
						.Finish();
					_inputProps[propertyInfo] = customAttribute;
				}
			}
			LcInputActionApi.RegisterInputActions(this, inputActionMapBuilder);
		}

		public virtual void CreateInputActions(in InputActionMapBuilder builder)
		{
		}

		public virtual void OnAssetLoaded()
		{
		}

		internal void BuildActionRefs()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<PropertyInfo, InputActionAttribute> inputProp in _inputProps)
			{
				inputProp.Deconstruct(out var key, out var value);
				PropertyInfo propertyInfo = key;
				InputActionAttribute inputActionAttribute = value;
				InputAction value2 = Asset.FindAction(inputActionAttribute.ActionId, false);
				propertyInfo.SetValue(this, value2);
			}
			IEnumerable<InputActionReference> collection = ((IEnumerable<InputActionMap>)(object)Asset.actionMaps).SelectMany((InputActionMap map) => (IEnumerable<InputAction>)(object)map.actions).Select((Func<InputAction, InputActionReference>)InputActionReference.Create);
			_actionRefs.AddRange(collection);
		}

		public void Enable()
		{
			WasEnabled = Asset.enabled;
			Asset.Enable();
		}

		public void Disable()
		{
			WasEnabled = Asset.enabled;
			Asset.Disable();
		}

		internal void Save()
		{
			BindingOverrides bindingOverrides = new BindingOverrides(Asset.bindings);
			File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides));
		}

		internal void Load()
		{
			try
			{
				ApplyMigrations();
			}
			catch (Exception ex)
			{
				Logging.Logger.LogError((object)"Got error when applying migrations, skipping...");
				Logging.Logger.LogError((object)ex);
			}
			if (!File.Exists(_jsonPath))
			{
				return;
			}
			try
			{
				BindingOverrides.FromJson(File.ReadAllText(_jsonPath)).LoadInto(Asset);
			}
			catch (Exception ex2)
			{
				Logging.Logger.LogError((object)ex2);
			}
		}

		private void ApplyMigrations()
		{
			string text = Path.Combine(FsUtils.Pre041ControlsDir, Id + ".json");
			if (File.Exists(text) && !File.Exists(_jsonPath))
			{
				File.Move(text, _jsonPath);
			}
		}
	}
}

BepInEx/plugins/LCBetterSaves.dll

Decompiled 8 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using LCBetterSaves;
using LCBetterSaves.Properties;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LCBetterSaves")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Better save files for Lethal Company")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0+c4704fdbef04f8b1a1445fc922475f8ee41eee5e")]
[assembly: AssemblyProduct("LCBetterSaves")]
[assembly: AssemblyTitle("LCBetterSaves")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class NewFileUISlot_BetterSaves : MonoBehaviour
{
	public Animator buttonAnimator;

	public Button button;

	public bool isSelected;

	public void Awake()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		buttonAnimator = ((Component)this).GetComponent<Animator>();
		button = ((Component)this).GetComponent<Button>();
		((UnityEvent)button.onClick).AddListener(new UnityAction(SetFileToThis));
	}

	public void SetFileToThis()
	{
		string currentSaveFileName = "LCSaveFile" + Plugin.newSaveFileNum;
		GameNetworkManager.Instance.currentSaveFileName = currentSaveFileName;
		GameNetworkManager.Instance.saveFileNum = Plugin.newSaveFileNum;
		SetButtonColorForAllFileSlots();
		isSelected = true;
		SetButtonColor();
	}

	public void SetButtonColorForAllFileSlots()
	{
		SaveFileUISlot_BetterSaves[] array = Object.FindObjectsOfType<SaveFileUISlot_BetterSaves>();
		SaveFileUISlot_BetterSaves[] array2 = array;
		foreach (SaveFileUISlot_BetterSaves saveFileUISlot_BetterSaves in array2)
		{
			saveFileUISlot_BetterSaves.SetButtonColor();
			saveFileUISlot_BetterSaves.deleteButton.SetActive(false);
			saveFileUISlot_BetterSaves.renameButton.SetActive(false);
		}
	}

	public void SetButtonColor()
	{
		buttonAnimator.SetBool("isPressed", isSelected);
	}
}
public class SaveFileUISlot_BetterSaves : MonoBehaviour
{
	public Animator buttonAnimator;

	public Button button;

	public TextMeshProUGUI fileStatsText;

	public int fileNum;

	public string fileString;

	public TextMeshProUGUI fileNotCompatibleAlert;

	public GameObject deleteButton;

	public GameObject renameButton;

	public void Awake()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		buttonAnimator = ((Component)this).GetComponent<Animator>();
		button = ((Component)this).GetComponent<Button>();
		((UnityEvent)button.onClick).AddListener(new UnityAction(SetFileToThis));
		fileStatsText = ((Component)((Component)this).transform.GetChild(2)).GetComponent<TextMeshProUGUI>();
		fileNotCompatibleAlert = ((Component)((Component)this).transform.GetChild(4)).GetComponent<TextMeshProUGUI>();
		deleteButton = ((Component)((Component)this).transform.GetChild(3)).gameObject;
	}

	public void Start()
	{
		UpdateStats();
	}

	private void OnEnable()
	{
		if (!Object.FindObjectOfType<MenuManager>().filesCompatible[fileNum])
		{
			((Behaviour)fileNotCompatibleAlert).enabled = true;
		}
	}

	public void UpdateStats()
	{
		try
		{
			if (ES3.FileExists(fileString))
			{
				int num = ES3.Load<int>("GroupCredits", fileString, 30);
				int num2 = ES3.Load<int>("Stats_DaysSpent", fileString, 0);
				((TMP_Text)fileStatsText).text = $"${num}\nDays: {num2}";
			}
			else
			{
				((TMP_Text)fileStatsText).text = "";
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("Error updating stats: " + ex.Message));
		}
	}

	public void SetButtonColor()
	{
		buttonAnimator.SetBool("isPressed", GameNetworkManager.Instance.currentSaveFileName == fileString);
	}

	public void SetFileToThis()
	{
		Plugin.fileToModify = fileNum;
		GameNetworkManager.Instance.currentSaveFileName = fileString;
		GameNetworkManager.Instance.saveFileNum = fileNum;
		SetButtonColorForAllFileSlots();
	}

	public void SetButtonColorForAllFileSlots()
	{
		SaveFileUISlot_BetterSaves[] array = Object.FindObjectsOfType<SaveFileUISlot_BetterSaves>();
		SaveFileUISlot_BetterSaves[] array2 = array;
		foreach (SaveFileUISlot_BetterSaves saveFileUISlot_BetterSaves in array2)
		{
			saveFileUISlot_BetterSaves.SetButtonColor();
			saveFileUISlot_BetterSaves.deleteButton.SetActive((Object)(object)saveFileUISlot_BetterSaves == (Object)(object)this);
			saveFileUISlot_BetterSaves.renameButton.SetActive((Object)(object)saveFileUISlot_BetterSaves == (Object)(object)this);
		}
		NewFileUISlot_BetterSaves newFileUISlot_BetterSaves = Object.FindObjectOfType<NewFileUISlot_BetterSaves>();
		newFileUISlot_BetterSaves.isSelected = false;
		newFileUISlot_BetterSaves.SetButtonColor();
	}
}
public class RenameFileButton_BetterSaves : MonoBehaviour
{
	public void RenameFile()
	{
		string text = $"LCSaveFile{Plugin.fileToModify}";
		string text2 = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/Panel/LobbyHostOptions/OptionsNormal/ServerNameField/Text Area/Text").GetComponent<TMP_Text>().text;
		if (ES3.FileExists(text))
		{
			ES3.Save<string>("Alias_BetterSaves", text2, text);
			Debug.Log((object)("Granted alias " + text2 + " to file " + text));
		}
		Plugin.RefreshNameFields();
	}
}
public class DeleteFileButton_BetterSaves : MonoBehaviour
{
	public int fileToDelete;

	public AudioClip deleteFileSFX;

	public TextMeshProUGUI deleteFileText;

	public void UpdateFileToDelete()
	{
		fileToDelete = Plugin.fileToModify;
		if (ES3.Load<string>("Alias_BetterSaves", $"LCSaveFile{fileToDelete}", "") != "")
		{
			((TMP_Text)deleteFileText).text = "Do you want to delete file (" + ES3.Load<string>("Alias_BetterSaves", $"LCSaveFile{fileToDelete}", "") + ")?";
		}
		else
		{
			((TMP_Text)deleteFileText).text = $"Do you want to delete File {fileToDelete + 1}?";
		}
	}

	public void DeleteFile()
	{
		string text = $"LCSaveFile{fileToDelete}";
		if (ES3.FileExists(text))
		{
			ES3.DeleteFile(text);
			Object.FindObjectOfType<MenuManager>().MenuAudio.PlayOneShot(deleteFileSFX);
		}
		SaveFileUISlot_BetterSaves[] array = Object.FindObjectsOfType<SaveFileUISlot_BetterSaves>(true);
		SaveFileUISlot_BetterSaves[] array2 = array;
		foreach (SaveFileUISlot_BetterSaves saveFileUISlot_BetterSaves in array2)
		{
			Debug.Log((object)$"Deleted {fileToDelete}");
			if (saveFileUISlot_BetterSaves.fileNum == fileToDelete)
			{
				((Behaviour)saveFileUISlot_BetterSaves.fileNotCompatibleAlert).enabled = false;
				Object.FindObjectOfType<MenuManager>().filesCompatible[fileToDelete] = true;
			}
		}
		Plugin.InitializeBetterSaves();
	}
}
namespace LCBetterSaves
{
	[BepInPlugin("LCBetterSaves", "LCBetterSaves", "1.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony = new Harmony("BetterSaves");

		public static int fileToModify = -1;

		public static int newSaveFileNum;

		public static Sprite renameSprite;

		public static MenuManager menuManager;

		public static AudioClip deleteFileSFX;

		public static TextMeshProUGUI deleteFileText;

		public static float buttonBaseY;

		public void Awake()
		{
			_harmony.PatchAll(typeof(Plugin));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LCBetterSaves is loaded!");
		}

		[HarmonyPatch(typeof(MenuManager), "Start")]
		public static void Postfix(MenuManager __instance)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			menuManager = __instance;
			if ((Object)(object)renameSprite == (Object)null)
			{
				AssetBundle val = AssetBundle.LoadFromMemory(Resources.lcbettersaves);
				Texture2D val2 = val.LoadAsset<Texture2D>("Assets/RenameSprite.png");
				renameSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
			}
			InitializeBetterSaves();
		}

		public static void InitializeBetterSaves()
		{
			try
			{
				DestroyBetterSavesButtons();
				DestroyOriginalSaveButtons();
				UpdateTopText();
				CreateModdedDeleteFileButton();
				CreateBetterSaveButtons();
				UpdateFilesPanelRect(CountSaveFiles());
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("An error occurred during initialization: " + ex.Message));
			}
		}

		public static void DestroyBetterSavesButtons()
		{
			try
			{
				SaveFileUISlot_BetterSaves[] array = Object.FindObjectsOfType<SaveFileUISlot_BetterSaves>();
				foreach (SaveFileUISlot_BetterSaves saveFileUISlot_BetterSaves in array)
				{
					Object.Destroy((Object)(object)((Component)saveFileUISlot_BetterSaves).gameObject);
				}
				NewFileUISlot_BetterSaves[] array2 = Object.FindObjectsOfType<NewFileUISlot_BetterSaves>();
				foreach (NewFileUISlot_BetterSaves newFileUISlot_BetterSaves in array2)
				{
					Object.Destroy((Object)(object)((Component)newFileUISlot_BetterSaves).gameObject);
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error occurred while destroying better saves buttons: " + ex.Message));
			}
		}

		public static void UpdateTopText()
		{
			GameObject val = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/EnterAName");
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Panel label not found.");
			}
			else
			{
				((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = "BetterSaves";
			}
		}

		public static void CreateModdedDeleteFileButton()
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			GameObject val = GameObject.Find("Canvas/MenuContainer/DeleteFileConfirmation/Panel/Delete");
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Delete file game object not found.");
				return;
			}
			if ((Object)(object)val.GetComponent<DeleteFileButton_BetterSaves>() != (Object)null)
			{
				Debug.LogWarning((object)"DeleteFileButton_BetterSaves component already exists on deleteFileGO");
				return;
			}
			DeleteFileButton component = val.GetComponent<DeleteFileButton>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)"DeleteFileButton component not found on deleteFileGO");
				return;
			}
			if ((Object)(object)deleteFileSFX == (Object)null)
			{
				deleteFileSFX = component.deleteFileSFX;
			}
			if ((Object)(object)deleteFileText == (Object)null)
			{
				deleteFileText = component.deleteFileText;
			}
			Object.Destroy((Object)(object)component);
			if ((Object)(object)val.GetComponent<DeleteFileButton_BetterSaves>() == (Object)null)
			{
				DeleteFileButton_BetterSaves deleteFileButton_BetterSaves = val.AddComponent<DeleteFileButton_BetterSaves>();
				deleteFileButton_BetterSaves.deleteFileSFX = deleteFileSFX;
				deleteFileButton_BetterSaves.deleteFileText = deleteFileText;
				Button component2 = val.GetComponent<Button>();
				if ((Object)(object)component2 != (Object)null)
				{
					((UnityEventBase)component2.onClick).RemoveAllListeners();
					((UnityEvent)component2.onClick).AddListener(new UnityAction(deleteFileButton_BetterSaves.DeleteFile));
				}
				else
				{
					Debug.LogError((object)"Button component not found on deleteFileGO");
				}
			}
			else
			{
				Debug.LogWarning((object)"DeleteFileButton_BetterSaves component already exists on deleteFileGO");
			}
		}

		public static void CreateBetterSaveButtons()
		{
			try
			{
				GameObject val = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File1");
				val.SetActive(true);
				int numSaves = CountSaveFiles();
				Debug.Log((object)("Positioning based on " + numSaves + " saves."));
				NewFileUISlot_BetterSaves newFileUISlot_BetterSaves = CreateNewFileNode(numSaves);
				List<string> list = NormalizeFileNames();
				newSaveFileNum = list.Count;
				menuManager.filesCompatible = new bool[16];
				for (int i = 0; i < menuManager.filesCompatible.Length; i++)
				{
					menuManager.filesCompatible[i] = true;
				}
				for (int j = 0; j < list.Count; j++)
				{
					CreateModdedSaveNode(int.Parse(list[j].Replace("LCSaveFile", "")), j, ((Component)newFileUISlot_BetterSaves).gameObject);
				}
				val.SetActive(false);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error occurred while refreshing save buttons: " + ex.Message));
			}
		}

		public static NewFileUISlot_BetterSaves CreateNewFileNode(int numSaves)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File1");
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Original GameObject not found.");
				return null;
			}
			Transform parent = val.transform.parent;
			SaveFileUISlot component = val.GetComponent<SaveFileUISlot>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, parent);
			((Object)val2).name = "NewFile";
			TMP_Text component2 = ((Component)val2.transform.GetChild(1)).GetComponent<TMP_Text>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.text = "New File";
				NewFileUISlot_BetterSaves newFileUISlot_BetterSaves = val2.AddComponent<NewFileUISlot_BetterSaves>();
				if ((Object)(object)newFileUISlot_BetterSaves == (Object)null)
				{
					Debug.LogError((object)"Failed to add NewFileUISlot_BetterSaves component.");
					return null;
				}
				Transform child = val2.transform.GetChild(3);
				if ((Object)(object)child != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
					try
					{
						RectTransform component3 = val2.GetComponent<RectTransform>();
						if (!((Object)(object)component3 != (Object)null))
						{
							Debug.LogError((object)"RectTransform component not found.");
							return null;
						}
						float x = component3.anchoredPosition.x;
						if (buttonBaseY == 0f)
						{
							buttonBaseY = component3.anchoredPosition.y - component3.sizeDelta.y * 1.75f;
						}
						float num = buttonBaseY + component3.sizeDelta.y * (float)numSaves / 2f;
						component3.anchoredPosition = new Vector2(x, num);
					}
					catch (Exception ex)
					{
						Debug.LogError((object)("Error setting anchored position: " + ex.Message));
						return null;
					}
					return newFileUISlot_BetterSaves;
				}
				Debug.LogError((object)"Delete button not found.");
				return null;
			}
			Debug.LogError((object)"Text component not found.");
			return null;
		}

		private static int CountSaveFiles()
		{
			int num = 0;
			string[] files = ES3.GetFiles();
			foreach (string text in files)
			{
				if (ES3.FileExists(text) && text.StartsWith("LCSaveFile"))
				{
					num++;
				}
			}
			return num;
		}

		public static void DestroyOriginalSaveButtons()
		{
			Object.Destroy((Object)(object)GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File2"));
			Object.Destroy((Object)(object)GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File3"));
		}

		public static List<string> NormalizeFileNames()
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			string[] files = ES3.GetFiles();
			foreach (string text in files)
			{
				if (ES3.FileExists(text) && text.StartsWith("LCSaveFile"))
				{
					Debug.Log((object)("Found file: " + text));
					list.Add(text);
				}
				if (ES3.FileExists(text) && text.StartsWith("LGU"))
				{
					Debug.Log((object)("Found LGU file: " + text));
					list2.Add(text);
				}
				else if (ES3.FileExists(text) && text.StartsWith("LCSaveFile"))
				{
					list2.Add("placeholder");
				}
			}
			int num = 0;
			foreach (string item in list)
			{
				string text2 = "TempFile" + num;
				ES3.RenameFile(item, text2);
				Debug.Log((object)("Renamed " + item + " to " + text2));
				num++;
			}
			num = 0;
			foreach (string item2 in list2)
			{
				if (item2 == "placeholder")
				{
					num++;
					continue;
				}
				string text3 = "LGUTempFile" + num;
				ES3.RenameFile(item2, text3);
				Debug.Log((object)("Renamed " + item2 + " to " + text3));
				num++;
			}
			int num2 = 0;
			List<string> list3 = new List<string>();
			foreach (string item3 in list)
			{
				string text4 = "TempFile" + num2;
				string text5 = "LCSaveFile" + num2;
				if (ES3.FileExists(text4))
				{
					ES3.RenameFile(text4, text5);
					list3.Add(text5);
					Debug.Log((object)("Renamed " + text4 + " to " + text5));
				}
				else
				{
					Debug.Log((object)("Temporary file " + text4 + " not found. It might have been moved or deleted."));
				}
				num2++;
			}
			num2 = 0;
			List<string> list4 = new List<string>();
			foreach (string item4 in list2)
			{
				string text6 = "LGUTempFile" + num2;
				string text7 = "LGU_" + num2;
				if (item4 == "placeholder")
				{
					num2++;
					continue;
				}
				if (ES3.FileExists(text6))
				{
					ES3.RenameFile(text6, text7);
					list3.Add(text7);
					Debug.Log((object)("Renamed " + text6 + " to " + text7));
				}
				else
				{
					Debug.Log((object)("Temporary file " + text6 + " not found. It might have been moved or deleted."));
				}
				num2++;
			}
			return list3;
		}

		public static void CreateModdedSaveNode(int fileIndex, int listIndex, GameObject newFileButton)
		{
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			int num = fileIndex + 1;
			GameObject val = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File1");
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Original GameObject not found.");
				return;
			}
			Transform parent = val.transform.parent;
			GameObject val2 = Object.Instantiate<GameObject>(val, parent);
			((Object)val2).name = "File" + num + "_BetterSaves";
			string text = ES3.Load<string>("Alias_BetterSaves", "LCSaveFile" + fileIndex, "");
			if (text == "")
			{
				((Component)val2.transform.GetChild(1)).GetComponent<TMP_Text>().text = "File " + num;
			}
			else
			{
				((Component)val2.transform.GetChild(1)).GetComponent<TMP_Text>().text = text;
			}
			val2.AddComponent<SaveFileUISlot_BetterSaves>();
			SaveFileUISlot_BetterSaves component = val2.GetComponent<SaveFileUISlot_BetterSaves>();
			if ((Object)(object)component != (Object)null)
			{
				component.fileNum = fileIndex;
				component.fileString = "LCSaveFile" + fileIndex;
				RectTransform component2 = val2.GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					float x = component2.anchoredPosition.x;
					float y = newFileButton.GetComponent<RectTransform>().anchoredPosition.y;
					float num2 = y - component2.sizeDelta.y * (float)num;
					component2.anchoredPosition = new Vector2(x, num2);
				}
				GameObject gameObject = ((Component)val2.transform.GetChild(3)).gameObject;
				DeleteFileButton_BetterSaves component3 = GameObject.Find("Canvas/MenuContainer/DeleteFileConfirmation/Panel/Delete").GetComponent<DeleteFileButton_BetterSaves>();
				((UnityEvent)gameObject.gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(component3.UpdateFileToDelete));
				gameObject.SetActive(false);
				component.renameButton = CreateRenameFileButton(val2);
			}
			else
			{
				Debug.LogError((object)"SaveFileUISlot_BetterSaves component not found on the cloned GameObject.");
				Object.Destroy((Object)(object)val2);
			}
		}

		public static GameObject CreateRenameFileButton(GameObject fileNode)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject gameObject = ((Component)fileNode.transform.GetChild(3)).gameObject;
				GameObject val = Object.Instantiate<GameObject>(gameObject, fileNode.transform);
				((Object)val).name = "RenameButton";
				val.GetComponent<Image>().sprite = renameSprite;
				Button component = val.GetComponent<Button>();
				component.onClick = new ButtonClickedEvent();
				val.AddComponent<RenameFileButton_BetterSaves>();
				RenameFileButton_BetterSaves component2 = val.GetComponent<RenameFileButton_BetterSaves>();
				if ((Object)(object)component2 != (Object)null)
				{
					((UnityEvent)component.onClick).AddListener(new UnityAction(component2.RenameFile));
				}
				else
				{
					Debug.LogError((object)"RenameFileButton_BetterSaves component not found on renameButton");
				}
				RectTransform component3 = val.GetComponent<RectTransform>();
				if ((Object)(object)component3 != (Object)null)
				{
					float num = ((Transform)component3).localPosition.x + 20f;
					float y = ((Transform)component3).localPosition.y;
					((Transform)component3).localPosition = Vector2.op_Implicit(new Vector2(num, y));
				}
				val.SetActive(false);
				return val;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error occurred while creating rename file button: " + ex.Message));
				return null;
			}
		}

		public static void UpdateFilesPanelRect(int numSaves)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject obj = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel");
				RectTransform val = ((obj != null) ? obj.GetComponent<RectTransform>() : null);
				if ((Object)(object)val == (Object)null)
				{
					throw new Exception("Failed to find FilesPanel RectTransform.");
				}
				Vector2 sizeDelta = val.sizeDelta;
				GameObject obj2 = GameObject.Find("Canvas/MenuContainer/LobbyHostSettings/FilesPanel/File1");
				RectTransform val2 = ((obj2 != null) ? obj2.GetComponent<RectTransform>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					throw new Exception("Failed to find File1 RectTransform.");
				}
				float y = val2.sizeDelta.y;
				sizeDelta.y = y * (float)(numSaves + 3);
				val.sizeDelta = sizeDelta;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Error occurred while updating files panel rect: " + ex.Message));
			}
		}

		public static void RefreshNameFields()
		{
			SaveFileUISlot_BetterSaves[] array = Object.FindObjectsOfType<SaveFileUISlot_BetterSaves>();
			SaveFileUISlot_BetterSaves[] array2 = array;
			foreach (SaveFileUISlot_BetterSaves saveFileUISlot_BetterSaves in array2)
			{
				string text = ES3.Load<string>("Alias_BetterSaves", saveFileUISlot_BetterSaves.fileString, "");
				if (text == "")
				{
					((Component)((Component)saveFileUISlot_BetterSaves).transform.GetChild(1)).GetComponent<TMP_Text>().text = "File " + (saveFileUISlot_BetterSaves.fileNum + 1);
				}
				else
				{
					((Component)((Component)saveFileUISlot_BetterSaves).transform.GetChild(1)).GetComponent<TMP_Text>().text = text;
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LCBetterSaves";

		public const string PLUGIN_NAME = "LCBetterSaves";

		public const string PLUGIN_VERSION = "1.4.0";
	}
}
namespace LCBetterSaves.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	public class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LCBetterSaves.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		public static byte[] lcbettersaves
		{
			get
			{
				object @object = ResourceManager.GetObject("lcbettersaves", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}

BepInEx/plugins/MoreEmotes1.2.2.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using MoreEmotes.Patch;
using Tools;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FuckYouMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FuckYouMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5ecc2bf2-af12-4e83-a6f1-cf2eacbf3060")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tools
{
	public class Reflection
	{
		public static object GetInstanceField(Type type, object instance, string fieldName)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(fieldName, bindingAttr);
			return field.GetValue(instance);
		}

		public static object CallMethod(object instance, string methodName, params object[] args)
		{
			MethodInfo method = instance.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
			if (method != null)
			{
				return method.Invoke(instance, args);
			}
			return null;
		}
	}
}
namespace MoreEmotes
{
	[BepInPlugin("MoreEmotes", "MoreEmotes-Sligili", "1.2.2")]
	public class FuckYouModInitialization : BaseUnityPlugin
	{
		private Harmony _harmony;

		private ConfigEntry<string> config_KeyWheel;

		private ConfigEntry<bool> config_InventoryCheck;

		private ConfigEntry<string> config_KeyEmote3;

		private ConfigEntry<string> config_KeyEmote4;

		private ConfigEntry<string> config_KeyEmote5;

		private ConfigEntry<string> config_KeyEmote6;

		private ConfigEntry<string> config_KeyEmote7;

		private ConfigEntry<string> config_KeyEmote8;

		private void Awake()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreEmotes loaded");
			EmotePatch.animationsBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animationsbundle"));
			EmotePatch.animatorBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MoreEmotes/animatorbundle"));
			EmotePatch.local = EmotePatch.animatorBundle.LoadAsset<RuntimeAnimatorController>("Assets/MoreEmotes/NEWmetarig.controller");
			EmotePatch.others = EmotePatch.animatorBundle.LoadAsset<RuntimeAnimatorController>("Assets/MoreEmotes/NEWmetarigOtherPlayers.controller");
			CustomAudioAnimationEvent.claps[0] = EmotePatch.animationsBundle.LoadAsset<AudioClip>("Assets/MoreEmotes/SingleClapEmote1.wav");
			CustomAudioAnimationEvent.claps[1] = EmotePatch.animationsBundle.LoadAsset<AudioClip>("Assets/MoreEmotes/SingleClapEmote2.wav");
			ConfigFile();
			IncompatibilityAids();
			_harmony = new Harmony("MoreEmotes");
			_harmony.PatchAll(typeof(EmotePatch));
		}

		private void IncompatibilityAids()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				BepInPlugin metadata = pluginInfo.Value.Metadata;
				if (metadata.GUID.Equals("com.malco.lethalcompany.moreshipupgrades") || metadata.GUID.Equals("Stoneman.LethalProgression"))
				{
					EmotePatch.IncompatibleStuff = true;
					break;
				}
			}
		}

		private void ConfigFile()
		{
			EmotePatch.keybinds = new string[9];
			config_KeyWheel = ((BaseUnityPlugin)this).Config.Bind<string>("EMOTE WHEEL", "Key", "v", (ConfigDescription)null);
			EmotePatch.wheelKeybind = config_KeyWheel.Value;
			config_InventoryCheck = ((BaseUnityPlugin)this).Config.Bind<bool>("OTHERS", "InventoryCheck", true, "Prevents some emotes from performing while holding any item/scrap");
			EmotePatch.InvCheck = config_InventoryCheck.Value;
			config_KeyEmote3 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Middle Finger", "3", (ConfigDescription)null);
			EmotePatch.keybinds[2] = config_KeyEmote3.Value.Replace(" ", "");
			config_KeyEmote4 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "The Griddy", "6", (ConfigDescription)null);
			EmotePatch.keybinds[5] = config_KeyEmote4.Value.Replace(" ", "");
			config_KeyEmote5 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Shy", "5", (ConfigDescription)null);
			EmotePatch.keybinds[4] = config_KeyEmote5.Value.Replace(" ", "");
			config_KeyEmote6 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Clap", "4", (ConfigDescription)null);
			EmotePatch.keybinds[3] = config_KeyEmote6.Value.Replace(" ", "");
			config_KeyEmote7 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Twerk", "7", (ConfigDescription)null);
			EmotePatch.keybinds[6] = config_KeyEmote7.Value.Replace(" ", "");
			config_KeyEmote8 = ((BaseUnityPlugin)this).Config.Bind<string>("QUICK EMOTES", "Salute", "8", (ConfigDescription)null);
			EmotePatch.keybinds[7] = config_KeyEmote8.Value.Replace(" ", "");
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "MoreEmotes";

		public const string Name = "MoreEmotes-Sligili";

		public const string Ver = "1.2.2";
	}
}
namespace MoreEmotes.Patch
{
	internal class EmotePatch
	{
		public static AssetBundle animationsBundle;

		public static AssetBundle animatorBundle;

		public static string[] keybinds;

		public static string wheelKeybind;

		private static CallbackContext context;

		public static RuntimeAnimatorController local;

		public static RuntimeAnimatorController others;

		private static int currentEmoteID;

		private static float svMovSpeed;

		public static bool IncompatibleStuff;

		public static bool InvCheck;

		public static bool emoteWheelIsOpened;

		public static GameObject wheel;

		public static GameObject rebindmenu;

		public static GameObject btn;

		private static SelectionWheel selectionWheel;

		[HarmonyPatch(typeof(MenuManager), "Start")]
		[HarmonyPostfix]
		private static void MenuStart(MenuManager __instance)
		{
			GameObject val = animationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesPanel.prefab");
			GameObject val2 = animationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesButton.prefab");
			GameObject gameObject = ((Component)((Component)__instance).transform.parent).gameObject;
			GameObject gameObject2 = ((Component)((Component)gameObject.transform.Find("MenuContainer")).transform.Find("SettingsPanel")).gameObject;
			if ((Object)(object)btn != (Object)null)
			{
				Object.Destroy((Object)(object)btn.gameObject);
			}
			btn = Object.Instantiate<GameObject>(val2, gameObject2.transform);
			btn.transform.SetSiblingIndex(7);
			if ((Object)(object)rebindmenu != (Object)null)
			{
				Object.Destroy((Object)(object)rebindmenu.gameObject);
			}
			rebindmenu = Object.Instantiate<GameObject>(val, gameObject2.transform);
			RebindBtn.defaultKeys = keybinds;
			BasicToggle.configValueInv = InvCheck;
			if ((Object)(object)gameObject2.GetComponent<SetupEverything>() == (Object)null)
			{
				gameObject2.AddComponent<SetupEverything>();
			}
			SetupEverything.configValue = InvCheck;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(PlayerControllerB __instance)
		{
			GameObject gameObject = ((Component)((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel")).transform.Find("metarig")).gameObject;
			CustomAudioAnimationEvent customAudioAnimationEvent = gameObject.AddComponent<CustomAudioAnimationEvent>();
			svMovSpeed = __instance.movementSpeed;
			customAudioAnimationEvent.player = __instance;
			if (Object.FindObjectsOfType(typeof(SelectionWheel)).Length == 0)
			{
				GameObject val = animationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesMenu.prefab");
				GameObject gameObject2 = ((Component)((Component)GameObject.Find("Systems").gameObject.transform.Find("UI")).gameObject.transform.Find("Canvas")).gameObject;
				GameObject val2 = animationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesPanel.prefab");
				GameObject val3 = animationsBundle.LoadAsset<GameObject>("Assets/MoreEmotes/Resources/MoreEmotesButton.prefab");
				GameObject gameObject3 = ((Component)((Component)gameObject2.transform.Find("QuickMenu")).transform.Find("SettingsPanel")).gameObject;
				if ((Object)(object)btn != (Object)null)
				{
					Object.Destroy((Object)(object)btn.gameObject);
				}
				btn = Object.Instantiate<GameObject>(val3, gameObject3.transform);
				btn.transform.SetSiblingIndex(7);
				if ((Object)(object)rebindmenu != (Object)null)
				{
					Object.Destroy((Object)(object)rebindmenu.gameObject);
				}
				rebindmenu = Object.Instantiate<GameObject>(val2, gameObject3.transform);
				RebindBtn.defaultKeys = keybinds;
				BasicToggle.configValueInv = InvCheck;
				if ((Object)(object)wheel != (Object)null)
				{
					Object.Destroy((Object)(object)wheel.gameObject);
				}
				wheel = Object.Instantiate<GameObject>(val, gameObject2.transform);
				selectionWheel = wheel.AddComponent<SelectionWheel>();
				SelectionWheel.emotes_Keybinds = new string[keybinds.Length + 1];
				SelectionWheel.emotes_Keybinds = keybinds;
				if ((Object)(object)gameObject3.GetComponent<SetupEverything>() == (Object)null)
				{
					gameObject3.AddComponent<SetupEverything>();
				}
				SetupEverything.configValue = InvCheck;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(PlayerControllerB __instance)
		{
			//IL_0231: 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)
			if (!__instance.isPlayerControlled || !((NetworkBehaviour)__instance).IsOwner)
			{
				__instance.playerBodyAnimator.runtimeAnimatorController = others;
				return;
			}
			if ((Object)(object)__instance.playerBodyAnimator != (Object)(object)local)
			{
				__instance.playerBodyAnimator.runtimeAnimatorController = local;
			}
			if (__instance.performingEmote)
			{
				currentEmoteID = __instance.playerBodyAnimator.GetInteger("emoteNumber");
			}
			if (!IncompatibleStuff)
			{
				bool flag = (bool)Reflection.CallMethod(__instance, "CheckConditionsForEmote") && currentEmoteID == 6 && __instance.performingEmote;
				__instance.movementSpeed = (flag ? (svMovSpeed / 2f) : svMovSpeed);
			}
			if (!PlayerPrefs.HasKey("InvCheck"))
			{
				PlayerPrefs.SetInt("InvCheck", InvCheck ? 1 : 0);
			}
			else
			{
				InvCheck = PlayerPrefs.GetInt("InvCheck") == 1;
			}
			if (!PlayerPrefs.HasKey("Emote_Wheel"))
			{
				PlayerPrefs.SetString("Emote_Wheel", wheelKeybind);
			}
			if (InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[PlayerPrefs.GetString("Emote_Wheel")], 0f) && !emoteWheelIsOpened && !__instance.isPlayerDead && !__instance.inTerminalMenu && !__instance.quickMenuManager.isMenuOpen)
			{
				emoteWheelIsOpened = true;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)2;
				wheel.SetActive(emoteWheelIsOpened);
				__instance.disableLookInput = true;
			}
			else if ((!InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[PlayerPrefs.GetString("Emote_Wheel")], 0f) && emoteWheelIsOpened) || __instance.quickMenuManager.isMenuOpen)
			{
				if (!__instance.quickMenuManager.isMenuOpen || __instance.isPlayerDead)
				{
					int selectedEmoteID = selectionWheel.selectedEmoteID;
					if (selectedEmoteID <= 3 || selectedEmoteID == 6 || !InvCheck)
					{
						__instance.PerformEmote(context, selectedEmoteID);
					}
					else if (!__instance.isHoldingObject)
					{
						__instance.PerformEmote(context, selectedEmoteID);
					}
					Cursor.visible = false;
					Cursor.lockState = (CursorLockMode)1;
				}
				if (__instance.isPlayerDead && !__instance.quickMenuManager.isMenuOpen)
				{
					Cursor.visible = false;
					Cursor.lockState = (CursorLockMode)1;
				}
				__instance.disableLookInput = false;
				emoteWheelIsOpened = false;
				wheel.SetActive(emoteWheelIsOpened);
			}
			if (!emoteWheelIsOpened && !__instance.quickMenuManager.isMenuOpen)
			{
				EmoteInput(keybinds[2], needsEmptyHands: false, 3, __instance);
				EmoteInput(keybinds[3], needsEmptyHands: true, 4, __instance);
				EmoteInput(keybinds[4], needsEmptyHands: true, 5, __instance);
				EmoteInput(keybinds[5], needsEmptyHands: false, 6, __instance);
				EmoteInput(keybinds[6], needsEmptyHands: true, 7, __instance);
				EmoteInput(keybinds[7], needsEmptyHands: true, 8, __instance);
			}
		}

		private static void EmoteInput(string keyBind, bool needsEmptyHands, int emoteID, PlayerControllerB player)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			bool flag = PlayerPrefs.GetInt("InvCheck") == 1;
			Emotes emotes = (Emotes)emoteID;
			string text = emotes.ToString();
			if (PlayerPrefs.HasKey(text))
			{
				keyBind = PlayerPrefs.GetString(text);
			}
			else
			{
				PlayerPrefs.SetString(text, keyBind);
			}
			if (!keyBind.Equals(string.Empty) && InputControlExtensions.IsPressed(((InputControl)Keyboard.current)[keyBind], 0f) && (!player.isHoldingObject || !needsEmptyHands || !flag) && (!player.performingEmote || currentEmoteID != emoteID))
			{
				Debug.Log((object)text);
				player.PerformEmote(context, emoteID);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "CheckConditionsForEmote")]
		[HarmonyPrefix]
		private static bool prefixCheckConditions(ref bool __result, PlayerControllerB __instance)
		{
			bool flag = (bool)Reflection.GetInstanceField(typeof(PlayerControllerB), __instance, "isJumping");
			if (currentEmoteID == 6)
			{
				__result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !flag && __instance.moveInputVector.x == 0f && !__instance.isSprinting && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu && !__instance.isTypingChat;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PerformEmote")]
		[HarmonyPrefix]
		private static void PerformEmotePrefix(CallbackContext context, int emoteID, PlayerControllerB __instance)
		{
			if ((emoteID >= 3 || emoteWheelIsOpened || ((CallbackContext)(ref context)).performed) && ((((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject)) || __instance.isTestingPlayer) && (bool)Reflection.CallMethod(__instance, "CheckConditionsForEmote") && !(__instance.timeSinceStartingEmote < 0.5f))
			{
				__instance.timeSinceStartingEmote = 0f;
				__instance.performingEmote = true;
				__instance.playerBodyAnimator.SetInteger("emoteNumber", emoteID);
				__instance.StartPerformingEmoteServerRpc();
			}
		}
	}
	public class CustomAudioAnimationEvent : MonoBehaviour
	{
		private Animator animator;

		private AudioSource SoundsSource;

		public static AudioClip[] claps = (AudioClip[])(object)new AudioClip[2];

		public PlayerControllerB player;

		private void Start()
		{
			animator = ((Component)this).GetComponent<Animator>();
			SoundsSource = player.movementAudio;
		}

		public void PlayClapSound()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			if (player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || animator.GetInteger("emoteNumber") == 4))
			{
				bool flag = player.isInHangarShipRoom && player.playersManager.hangarDoorsClosed;
				RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 22f, 0.6f, 0, flag, 6);
				SoundsSource.pitch = Random.Range(0.59f, 0.79f);
				SoundsSource.PlayOneShot(claps[Random.Range(0, claps.Length)]);
			}
		}

		public void PlayFootstepSound()
		{
			if (player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || animator.GetInteger("emoteNumber") == 6 || animator.GetInteger("emoteNumber") == 8) && ((Vector2)(ref player.moveInputVector)).sqrMagnitude == 0f)
			{
				player.PlayFootstepLocal();
				player.PlayFootstepServer();
			}
		}
	}
	public enum Emotes
	{
		Dance = 1,
		Point,
		Middle_Finger,
		Clap,
		Shy,
		The_Griddy,
		Twerk,
		Salute
	}
	public class SelectionWheel : MonoBehaviour
	{
		public RectTransform selectionBlock;

		public Text emoteInformation;

		public Text pageInformation;

		private int blocksNumber = 8;

		private int currentBlock = 1;

		public int pageNumber;

		public int selectedEmoteID;

		private float angle;

		private float pageCooldown = 0.1f;

		public GameObject[] Pages;

		private int cuadrante = 0;

		public string selectedEmoteName;

		public float wheelMovementOffset = 3.3f;

		public static string[] emotes_Keybinds;

		private Vector2 center;

		private void OnEnable()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			center = new Vector2((float)(Screen.width / 2), (float)(Screen.height / 2));
			PlayerInput component = GameObject.Find("PlayerSettingsObject").GetComponent<PlayerInput>();
			emotes_Keybinds[0] = InputActionRebindingExtensions.GetBindingDisplayString(component.currentActionMap.FindAction("Emote1", false), 0, (DisplayStringOptions)0);
			emotes_Keybinds[1] = InputActionRebindingExtensions.GetBindingDisplayString(component.currentActionMap.FindAction("Emote2", false), 0, (DisplayStringOptions)0);
			Cursor.visible = true;
			selectionBlock = ((Component)((Component)this).gameObject.transform.Find("SelectedEmote")).gameObject.GetComponent<RectTransform>();
			GameObject gameObject = ((Component)((Component)this).gameObject.transform.Find("FunctionalContent")).gameObject;
			emoteInformation = ((Component)((Component)((Component)this).gameObject.transform.Find("Graphics")).gameObject.transform.Find("EmoteInfo")).GetComponent<Text>();
			Pages = (GameObject[])(object)new GameObject[gameObject.transform.childCount];
			pageInformation = ((Component)((Component)((Component)this).gameObject.transform.Find("Graphics")).gameObject.transform.Find("PageNumber")).GetComponent<Text>();
			pageInformation.text = "Page " + Pages.Length + "/" + (pageNumber + 1);
			for (int i = 0; i < gameObject.transform.childCount; i++)
			{
				Pages[i] = ((Component)gameObject.transform.GetChild(i)).gameObject;
			}
			Mouse.current.WarpCursorPosition(center);
		}

		private void Update()
		{
			wheelSelection();
			pageSelection();
			selectedEmoteID = currentBlock + Mathf.RoundToInt((float)(blocksNumber / 4)) + blocksNumber * pageNumber;
			displayEmoteInfo();
		}

		private void wheelSelection()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			if (!(Vector2.Distance(center, ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue()) < wheelMovementOffset))
			{
				bool flag = ((InputControl<float>)(object)((Pointer)Mouse.current).position.x).ReadValue() > center.x;
				bool flag2 = ((InputControl<float>)(object)((Pointer)Mouse.current).position.y).ReadValue() > center.y;
				cuadrante = ((!flag) ? (flag2 ? 2 : 3) : (flag2 ? 1 : 4));
				float num = (((InputControl<float>)(object)((Pointer)Mouse.current).position.y).ReadValue() - center.y) / (((InputControl<float>)(object)((Pointer)Mouse.current).position.x).ReadValue() - center.x);
				float num2 = 180 * (cuadrante - ((cuadrante <= 2) ? 1 : 2));
				angle = Mathf.Atan(num) * (180f / (float)Math.PI) + num2;
				if (angle == 90f)
				{
					angle = 270f;
				}
				else if (angle == 270f)
				{
					angle = 90f;
				}
				float num3 = 360 / blocksNumber;
				currentBlock = Mathf.RoundToInt((angle - num3 * 1.5f) / num3);
				((Transform)selectionBlock).localRotation = Quaternion.Euler(((Component)this).transform.rotation.z, ((Component)this).transform.rotation.y, num3 * (float)currentBlock);
			}
		}

		private void pageSelection()
		{
			pageInformation.text = "Page " + Pages.Length + "/" + (pageNumber + 1);
			if (pageCooldown > 0f)
			{
				pageCooldown -= Time.deltaTime;
			}
			else if (((InputControl<float>)(object)((Vector2Control)Mouse.current.scroll).y).ReadValue() != 0f)
			{
				GameObject[] pages = Pages;
				foreach (GameObject val in pages)
				{
					val.SetActive(false);
				}
				int num = ((((InputControl<float>)(object)((Vector2Control)Mouse.current.scroll).y).ReadValue() > 0f) ? 1 : (-1));
				if (pageNumber + 1 > Pages.Length - 1 && num > 0)
				{
					pageNumber = 0;
				}
				else if (pageNumber - 1 < 0 && num < 0)
				{
					pageNumber = Pages.Length - 1;
				}
				else
				{
					pageNumber += num;
				}
				Pages[pageNumber].SetActive(true);
				pageCooldown = 0.1f;
			}
		}

		private void displayEmoteInfo()
		{
			string text = ((selectedEmoteID > emotes_Keybinds.Length) ? "" : emotes_Keybinds[selectedEmoteID - 1]);
			object obj;
			if (selectedEmoteID <= Enum.GetValues(typeof(Emotes)).Length)
			{
				Emotes emotes = (Emotes)selectedEmoteID;
				obj = emotes.ToString().Replace("_", " ");
			}
			else
			{
				obj = "EMPTY";
			}
			string text2 = (string)obj;
			if (!PlayerPrefs.HasKey(text2.Replace(" ", "_")))
			{
				PlayerPrefs.SetString(text2.Replace(" ", "_"), (selectedEmoteID > emotes_Keybinds.Length) ? "" : emotes_Keybinds[selectedEmoteID - 1]);
			}
			else
			{
				text = PlayerPrefs.GetString(text2.Replace(" ", "_"));
			}
			emoteInformation.text = text2 + "\n[" + text.ToUpper() + "]";
		}
	}
	public class RebindBtn : MonoBehaviour
	{
		public string defaultKey;

		public static string[] defaultKeys;

		public string playerPrefs;

		public GameObject waitingForInput;

		public Text keyInfo;

		public Text description;

		private void Start()
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			string text = ((Component)((Component)this).gameObject.transform.Find("Description")).GetComponent<Text>().text;
			try
			{
				int num = (int)(Emotes)Enum.Parse(typeof(Emotes), text.Replace(" ", "_"));
				defaultKey = defaultKeys[num - 1];
			}
			catch
			{
				defaultKey = "V";
			}
			playerPrefs = ((Component)((Component)this).gameObject.transform.Find("Description")).GetComponent<Text>().text.Replace(" ", "_");
			((Component)((Component)((Component)this).transform.parent).transform.Find("Delete")).gameObject.AddComponent<DeleteBtn>();
			keyInfo = ((Component)((Component)this).transform.Find("InputText")).GetComponent<Text>();
			waitingForInput = ((Component)((Component)this).transform.Find("wait")).gameObject;
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(GetKey));
			if (!PlayerPrefs.HasKey(playerPrefs))
			{
				PlayerPrefs.SetString(playerPrefs, defaultKey);
			}
			SetKeybind(PlayerPrefs.GetString(playerPrefs));
		}

		public void SetKeybind(string key)
		{
			PlayerPrefs.SetString(playerPrefs, key);
			keyInfo.text = key;
			((MonoBehaviour)this).StopAllCoroutines();
			waitingForInput.SetActive(false);
		}

		public void GetKey()
		{
			waitingForInput.SetActive(true);
			((MonoBehaviour)this).StartCoroutine(WaitForKey(delegate(string key)
			{
				SetKeybind(key);
			}));
		}

		private IEnumerator WaitForKey(Action<string> callback)
		{
			while (!((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame)
			{
				yield return (object)new WaitForEndOfFrame();
				Observable.CallOnce<InputControl>(InputSystem.onAnyButtonPress, (Action<InputControl>)delegate(InputControl ctrl)
				{
					callback((ctrl.device == Keyboard.current) ? ctrl.name : defaultKey);
				});
			}
		}
	}
	public class DeleteBtn : MonoBehaviour
	{
		private RebindBtn rebindBtn;

		private void Start()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			rebindBtn = ((Component)((Component)((Component)this).transform.parent).transform.Find("Button")).GetComponent<RebindBtn>();
			Button component = ((Component)this).GetComponent<Button>();
			((UnityEvent)component.onClick).AddListener(new UnityAction(deleteKey));
		}

		public void deleteKey()
		{
			rebindBtn.SetKeybind(string.Empty);
		}
	}
	public class BasicToggle : MonoBehaviour
	{
		private Toggle tog;

		public static bool configValueInv;

		public string playerPrefs;

		private void Start()
		{
			tog = ((Component)this).GetComponent<Toggle>();
			((UnityEvent<bool>)(object)tog.onValueChanged).AddListener((UnityAction<bool>)SetNewValue);
			if (!PlayerPrefs.HasKey(playerPrefs))
			{
				PlayerPrefs.SetInt(playerPrefs, configValueInv ? 1 : 0);
			}
		}

		public void SetNewValue(bool arg)
		{
			PlayerPrefs.SetInt(playerPrefs, tog.isOn ? 1 : 0);
		}
	}
	public class ButtonBasic : MonoBehaviour
	{
		public GameObject[] alternateActive = (GameObject[])(object)new GameObject[1];

		private void Start()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener(new UnityAction(onButtonTrigger));
			if (((Object)((Component)this).gameObject).name.Equals("BackButton"))
			{
				alternateActive[0] = ((Component)((Component)this).transform.parent).gameObject;
			}
			if (((Object)((Component)this).gameObject).name.Equals("MoreEmotesButton(Clone)"))
			{
				alternateActive[0] = ((Component)((Component)((Component)this).transform.parent).gameObject.transform.Find("MoreEmotesPanel(Clone)")).gameObject;
			}
		}

		public void onButtonTrigger()
		{
			GameObject[] array = alternateActive;
			foreach (GameObject val in array)
			{
				val.SetActive((!val.activeInHierarchy) ? true : false);
			}
		}
	}
	public class SetupEverything : MonoBehaviour
	{
		private GameObject panel;

		public static bool configValue;

		private void Start()
		{
			panel = ((Component)((Component)this).transform.Find("MoreEmotesPanel(Clone)")).gameObject;
			((Component)panel.transform.Find("Version")).GetComponent<Text>().text = "Sligili - 1.2.2";
			if (!PlayerPrefs.HasKey("InvCheck"))
			{
				PlayerPrefs.SetInt("InvCheck", configValue ? 1 : 0);
			}
			SetupMenuButton();
			BackButton();
			KeybindButtons();
			Others();
		}

		private void SetupMenuButton()
		{
			GameObject gameObject = ((Component)((Component)this).transform.Find("MoreEmotesButton(Clone)")).gameObject;
			gameObject.AddComponent<ButtonBasic>();
		}

		private void BackButton()
		{
			GameObject gameObject = ((Component)panel.transform.Find("BackButton")).gameObject;
			gameObject.AddComponent<ButtonBasic>();
		}

		private void KeybindButtons()
		{
			GameObject gameObject = ((Component)panel.transform.Find("KeybindButtons")).gameObject;
			GameObject[] array = (GameObject[])(object)new GameObject[gameObject.transform.childCount];
			for (int i = 0; i < gameObject.transform.childCount; i++)
			{
				array[i] = ((Component)gameObject.transform.GetChild(i)).gameObject;
			}
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				((Component)val.transform.Find("Button")).gameObject.AddComponent<RebindBtn>();
			}
		}

		private void Others()
		{
			GameObject gameObject = ((Component)panel.transform.Find("Inv")).gameObject;
			gameObject.AddComponent<BasicToggle>();
			BasicToggle basicToggle = gameObject.AddComponent<BasicToggle>();
			basicToggle.playerPrefs = "InvCheck";
		}
	}
}

BepInEx/plugins/MirrorDecor.dll

Decompiled 8 months ago
using System;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using MoreCompany.Cosmetics;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MirrorDecor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod for Lethal Company that adds a working mirror decoration that you can buy for your ship!")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyInformationalVersion("1.1.6")]
[assembly: AssemblyProduct("MirrorDecor")]
[assembly: AssemblyTitle("MirrorDecor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MirrorDecor
{
	public class Config
	{
		public static ConfigEntry<bool> mirrorEnabled;

		public static ConfigEntry<int> mirrorPrice;

		public static ConfigEntry<bool> alwaysAvailable;

		public static ConfigEntry<int> resolution;

		public static void Load()
		{
			mirrorEnabled = Plugin.config.Bind<bool>("Mirror", "MirrorEnabled", true, "Will you be able to purchase the mirror?");
			mirrorPrice = Plugin.config.Bind<int>("Mirror", "MirrorPrice", 100, "What will be the price of the mirror?");
			alwaysAvailable = Plugin.config.Bind<bool>("Mirror", "AlwaysAvailable", true, "Is the mirror always available to purchase from the store?");
			resolution = Plugin.config.Bind<int>("Mirror", "MirrorResolution", 2000, "What is the resolution/quality of the mirror image? (ex. 2000 = 2000x2000 pixels)");
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
	internal class CosmeticPatch
	{
		private static void Postfix()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				return;
			}
			CosmeticApplication val = Object.FindObjectOfType<CosmeticApplication>();
			if (CosmeticRegistry.locallySelectedCosmetics.Count <= 0 || val.spawnedCosmetics.Count > 0)
			{
				return;
			}
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				val.ApplyCosmetic(locallySelectedCosmetic, true);
			}
			foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
				SetAllChildrenLayer(((Component)spawnedCosmetic).transform, 23);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, string layerName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			int layer = LayerMask.NameToLayer(layerName);
			((Component)transform).gameObject.layer = layer;
			foreach (Transform item in transform)
			{
				SetAllChildrenLayer(item, layerName);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, int layer)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			((Component)transform).gameObject.layer = layer;
			foreach (Transform item in transform)
			{
				SetAllChildrenLayer(item, layer);
			}
		}
	}
	public class CustomUnlockable
	{
		public string name = "";

		public string unlockablePath = "";

		public string infoPath = "";

		public Action<UnlockableItem> unlockableAction = delegate
		{
		};

		public bool enabled = true;

		public int unlockCost = -1;

		public CustomUnlockable(string name, string unlockablePath, string infoPath, Action<UnlockableItem> action = null, int unlockCost = -1)
		{
			this.name = name;
			this.unlockablePath = unlockablePath;
			this.infoPath = infoPath;
			if (action != null)
			{
				unlockableAction = action;
			}
			this.unlockCost = unlockCost;
		}

		public static CustomUnlockable Add(string name, string unlockablePath, string infoPath = null, Action<UnlockableItem> action = null, int unlockCost = -1, bool enabled = true)
		{
			return new CustomUnlockable(name, unlockablePath, infoPath, action, unlockCost)
			{
				enabled = enabled
			};
		}
	}
	public class MirrorScript : MonoBehaviour
	{
		private void Update()
		{
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
	internal class PlayerPatch
	{
		private static void Postfix(ref PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				PlayerControllerB obj = __instance;
				((Renderer)obj.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				((Component)obj.thisPlayerModel).gameObject.layer = 23;
				((Component)obj.thisPlayerModelArms).gameObject.layer = 5;
			}
		}
	}
	[BepInPlugin("quackandcheese.mirrordecor", "MirrorDecor", "1.1.6")]
	[BepInDependency("evaisa.lethallib", "0.3.1")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "quackandcheese.mirrordecor";

		public const string ModName = "MirrorDecor";

		public const string ModVersion = "1.1.6";

		public static AssetBundle Bundle;

		public static ConfigFile config;

		public static ManualLogSource logger;

		public static List<CustomUnlockable> customUnlockables;

		private void Awake()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			Bundle = QuickLoadAssetBundle("mirror.assets");
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			new Harmony("quackandcheese.mirrordecor").PatchAll();
			Config.Load();
			RegisterItems();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MirrorDecor is loaded!");
		}

		private void RegisterItems()
		{
			customUnlockables = new List<CustomUnlockable> { CustomUnlockable.Add("Mirror", "Assets/Mirror/Unlockables/Mirror/Mirror.asset", "Assets/Mirror/Unlockables/Mirror/MirrorInfo.asset", null, Config.mirrorPrice.Value, Config.mirrorEnabled.Value) };
			Bundle.LoadAsset<UnlockableItemDef>("Assets/Mirror/Unlockables/Mirror/Mirror.asset").unlockable.alwaysInStock = Config.alwaysAvailable.Value;
			RenderTexture renderTexture = Bundle.LoadAsset<RenderTexture>("Assets/Mirror/Materials/Mirror.renderTexture");
			int value = Config.resolution.Value;
			Resize(renderTexture, value, value);
			foreach (CustomUnlockable customUnlockable in customUnlockables)
			{
				if (customUnlockable.enabled)
				{
					UnlockableItem unlockable = Bundle.LoadAsset<UnlockableItemDef>(customUnlockable.unlockablePath).unlockable;
					if ((Object)(object)unlockable.prefabObject != (Object)null)
					{
						NetworkPrefabs.RegisterNetworkPrefab(unlockable.prefabObject);
					}
					TerminalNode val = null;
					if (customUnlockable.infoPath != null)
					{
						val = Bundle.LoadAsset<TerminalNode>(customUnlockable.infoPath);
					}
					Unlockables.RegisterUnlockable(unlockable, (StoreType)2, (TerminalNode)null, (TerminalNode)null, val, customUnlockable.unlockCost);
				}
			}
		}

		public static T FindAsset<T>(string name) where T : Object
		{
			return Resources.FindObjectsOfTypeAll<T>().ToList().Find((T x) => ((Object)x).name == name);
		}

		public static AssetBundle QuickLoadAssetBundle(string assetBundleName)
		{
			return AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assetBundleName));
		}

		private void Resize(RenderTexture renderTexture, int width, int height)
		{
			if (Object.op_Implicit((Object)(object)renderTexture))
			{
				renderTexture.Release();
				((Texture)renderTexture).width = width;
				((Texture)renderTexture).height = height;
			}
		}

		public void sendModInfo()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Value.Metadata.GUID.Contains("ModSync"))
				{
					try
					{
						List<string> list = new List<string> { "quackandcheese", "MirrorDecor" };
						((Component)pluginInfo.Value.Instance).BroadcastMessage("getModInfo", (object)list, (SendMessageOptions)1);
						break;
					}
					catch (Exception)
					{
						logger.LogInfo((object)"Failed to send info to ModSync, go yell at Minx");
						break;
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MirrorDecor";

		public const string PLUGIN_NAME = "MirrorDecor";

		public const string PLUGIN_VERSION = "1.1.6";
	}
}

BepInEx/plugins/ModelReplacementAPI.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCThirdPerson;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
using ModelReplacement.Modules;
using MoreCompany.Cosmetics;
using Steamworks.Data;
using TooManyEmotes;
using TooManyEmotes.Patches;
using UnityEngine;
using UnityEngine.LowLevel;
using UnityEngine.PlayerLoop;
using UnityEngine.Pool;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Serialization;
using _3rdPerson.Helper;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ModelReplacementAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("https://github.com/BunyaPineTree/LethalCompany_ModelReplacementAPI")]
[assembly: AssemblyProduct("meow.ModelReplacementAPI")]
[assembly: AssemblyCopyright("Copyright © meow 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6390E70C-AB5E-42ED-BA29-F173942DC3A9")]
[assembly: AssemblyFileVersion("2.2.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(GrabbableObject))]
public class LocateHeldObjectsOnModelReplacementPatch
{
	[HarmonyPatch("LateUpdate")]
	[HarmonyPostfix]
	public static void LateUpdatePatch(ref GrabbableObject __instance)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance.parentObject == (Object)null) && !((Object)(object)__instance.playerHeldBy == (Object)null))
		{
			BodyReplacementBase component = ((Component)__instance.playerHeldBy).gameObject.GetComponent<BodyReplacementBase>();
			if (!((Object)(object)component == (Object)null) && component.viewState.GetViewState() == ViewState.ThirdPerson)
			{
				Transform itemHolder = component.avatar.itemHolder;
				itemHolder.localPosition = component.avatar.itemHolderPositionOffset;
				Transform playerItemHolder = component.avatar.GetPlayerItemHolder();
				((Component)__instance).transform.rotation = playerItemHolder.rotation;
				((Component)__instance).transform.Rotate(__instance.itemProperties.rotationOffset);
				((Component)__instance).transform.position = itemHolder.position;
				Vector3 positionOffset = __instance.itemProperties.positionOffset;
				positionOffset = playerItemHolder.rotation * positionOffset;
				Transform transform = ((Component)__instance).transform;
				transform.position += positionOffset;
			}
		}
	}
}
[HarmonyPatch(typeof(StartOfRound))]
public class RepairBrokenBodyReplacementsPatch
{
	[HarmonyPatch("ReviveDeadPlayers")]
	[HarmonyPostfix]
	public static void ReviveDeadPlayersPatch(ref StartOfRound __instance)
	{
		PlayerControllerB[] allPlayerScripts = __instance.allPlayerScripts;
		foreach (PlayerControllerB val in allPlayerScripts)
		{
			if (val.isPlayerDead && !((Object)(object)((Component)val).gameObject.GetComponent<BodyReplacementBase>() == (Object)null))
			{
				Console.WriteLine("Reinstantiating model replacement for " + val.playerUsername + " ");
				Type type = ((object)((Component)val).gameObject.GetComponent<BodyReplacementBase>()).GetType();
				Object.Destroy((Object)(object)((Component)val).gameObject.GetComponent<BodyReplacementBase>());
				((Component)val).gameObject.AddComponent(type);
			}
		}
	}
}
namespace JigglePhysics
{
	public static class CachedSphereCollider
	{
		private class DestroyListener : MonoBehaviour
		{
			private void OnDestroy()
			{
				_hasSphere = false;
			}
		}

		private static bool _hasSphere;

		private static SphereCollider _sphereCollider;

		public static void StartPass()
		{
			if (TryGet(out var collider))
			{
				((Collider)collider).enabled = true;
			}
		}

		public static void FinishedPass()
		{
			if (TryGet(out var collider))
			{
				((Collider)collider).enabled = false;
			}
		}

		public static bool TryGet(out SphereCollider collider)
		{
			//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_004f: Expected O, but got Unknown
			if (_hasSphere)
			{
				collider = _sphereCollider;
				return true;
			}
			try
			{
				GameObject val = new GameObject("JiggleBoneSphereCollider", new Type[2]
				{
					typeof(SphereCollider),
					typeof(DestroyListener)
				})
				{
					hideFlags = (HideFlags)61
				};
				if (Application.isPlaying)
				{
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				_sphereCollider = val.GetComponent<SphereCollider>();
				collider = _sphereCollider;
				((Collider)collider).enabled = false;
				_hasSphere = true;
				return true;
			}
			catch
			{
				if ((Object)(object)_sphereCollider != (Object)null)
				{
					if (Application.isPlaying)
					{
						Object.Destroy((Object)(object)((Component)_sphereCollider).gameObject);
					}
					else
					{
						Object.DestroyImmediate((Object)(object)((Component)_sphereCollider).gameObject);
					}
				}
				_hasSphere = false;
				collider = null;
				throw;
			}
		}
	}
	public class JiggleBone
	{
		private readonly bool hasTransform;

		private readonly PositionSignal targetAnimatedBoneSignal;

		private Vector3 currentFixedAnimatedBonePosition;

		public readonly JiggleBone parent;

		private JiggleBone child;

		private Quaternion boneRotationChangeCheck;

		private Vector3 bonePositionChangeCheck;

		private Quaternion lastValidPoseBoneRotation;

		private float projectionAmount;

		private Vector3 lastValidPoseBoneLocalPosition;

		private float normalizedIndex;

		public readonly Transform transform;

		private readonly PositionSignal particleSignal;

		private Vector3 workingPosition;

		private Vector3? preTeleportPosition;

		private Vector3 extrapolatedPosition;

		private float GetLengthToParent()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (parent == null)
			{
				return 0.1f;
			}
			return Vector3.Distance(currentFixedAnimatedBonePosition, parent.currentFixedAnimatedBonePosition);
		}

		public JiggleBone(Transform transform, JiggleBone parent, float projectionAmount = 1f)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003c: 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)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			this.transform = transform;
			this.parent = parent;
			this.projectionAmount = projectionAmount;
			Vector3 startPosition;
			if ((Object)(object)transform != (Object)null)
			{
				lastValidPoseBoneRotation = transform.localRotation;
				lastValidPoseBoneLocalPosition = transform.localPosition;
				startPosition = transform.position;
			}
			else
			{
				startPosition = GetProjectedPosition();
			}
			targetAnimatedBoneSignal = new PositionSignal(startPosition, Time.timeAsDouble);
			particleSignal = new PositionSignal(startPosition, Time.timeAsDouble);
			hasTransform = (Object)(object)transform != (Object)null;
			if (parent != null)
			{
				this.parent.child = this;
			}
		}

		public void CalculateNormalizedIndex()
		{
			int num = 0;
			JiggleBone jiggleBone = this;
			while (jiggleBone.parent != null)
			{
				jiggleBone = jiggleBone.parent;
				num++;
			}
			int num2 = 0;
			jiggleBone = this;
			while (jiggleBone.child != null)
			{
				jiggleBone = jiggleBone.child;
				num2++;
			}
			int num3 = num + num2;
			float num4 = (float)num / (float)num3;
			normalizedIndex = num4;
		}

		public void VerletPass(JiggleSettingsData jiggleSettings, Vector3 wind, double time)
		{
			//IL_0009: 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)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			currentFixedAnimatedBonePosition = targetAnimatedBoneSignal.SamplePosition(time);
			if (parent == null)
			{
				workingPosition = currentFixedAnimatedBonePosition;
				particleSignal.SetPosition(workingPosition, time);
			}
			else
			{
				Vector3 localSpaceVelocity = particleSignal.GetCurrent() - particleSignal.GetPrevious() - (parent.particleSignal.GetCurrent() - parent.particleSignal.GetPrevious());
				workingPosition = NextPhysicsPosition(particleSignal.GetCurrent(), particleSignal.GetPrevious(), localSpaceVelocity, Time.fixedDeltaTime, jiggleSettings.gravityMultiplier, jiggleSettings.friction, jiggleSettings.airDrag);
				workingPosition += wind * (Time.fixedDeltaTime * jiggleSettings.airDrag);
			}
		}

		public void CollisionPreparePass(JiggleSettingsData jiggleSettings)
		{
			//IL_0004: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			workingPosition = ConstrainLengthBackwards(workingPosition, jiggleSettings.lengthElasticity * jiggleSettings.lengthElasticity * 0.5f);
		}

		public void ConstraintPass(JiggleSettingsData jiggleSettings)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (parent != null)
			{
				workingPosition = ConstrainAngle(workingPosition, jiggleSettings.angleElasticity * jiggleSettings.angleElasticity, jiggleSettings.elasticitySoften);
				workingPosition = ConstrainLength(workingPosition, jiggleSettings.lengthElasticity * jiggleSettings.lengthElasticity);
			}
		}

		public void CollisionPass(JiggleSettingsBase jiggleSettings, List<Collider> colliders)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			if (colliders.Count == 0 || !CachedSphereCollider.TryGet(out var collider))
			{
				return;
			}
			Vector3 val = default(Vector3);
			float num = default(float);
			foreach (Collider collider2 in colliders)
			{
				collider.radius = jiggleSettings.GetRadius(normalizedIndex);
				if (!(collider.radius <= 0f) && Physics.ComputePenetration((Collider)(object)collider, workingPosition, Quaternion.identity, collider2, ((Component)collider2).transform.position, ((Component)collider2).transform.rotation, ref val, ref num))
				{
					workingPosition += val * num;
				}
			}
		}

		public void SignalWritePosition(double time)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			particleSignal.SetPosition(workingPosition, time);
		}

		private Vector3 GetProjectedPosition()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = parent.transform.position;
			return parent.transform.TransformPoint(parent.GetParentTransform().InverseTransformPoint(position) * projectionAmount);
		}

		private Vector3 GetTransformPosition()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTransform)
			{
				return GetProjectedPosition();
			}
			return transform.position;
		}

		private Transform GetParentTransform()
		{
			if (parent != null)
			{
				return parent.transform;
			}
			return transform.parent;
		}

		private void CacheAnimationPosition()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			//IL_0061: 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)
			if (!hasTransform)
			{
				targetAnimatedBoneSignal.SetPosition(GetProjectedPosition(), Time.timeAsDouble);
				return;
			}
			targetAnimatedBoneSignal.SetPosition(transform.position, Time.timeAsDouble);
			lastValidPoseBoneRotation = transform.localRotation;
			lastValidPoseBoneLocalPosition = transform.localPosition;
		}

		private Vector3 ConstrainLengthBackwards(Vector3 newPosition, float elasticity)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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)
			if (child == null)
			{
				return newPosition;
			}
			Vector3 val = newPosition - child.workingPosition;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.Lerp(newPosition, child.workingPosition + normalized * child.GetLengthToParent(), elasticity);
		}

		private Vector3 ConstrainLength(Vector3 newPosition, float elasticity)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0027: 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_0033: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = newPosition - parent.workingPosition;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.Lerp(newPosition, parent.workingPosition + normalized * GetLengthToParent(), elasticity);
		}

		public void MatchAnimationInstantly()
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			double timeAsDouble = Time.timeAsDouble;
			Vector3 transformPosition = GetTransformPosition();
			targetAnimatedBoneSignal.FlattenSignal(timeAsDouble, transformPosition);
			particleSignal.FlattenSignal(timeAsDouble, transformPosition);
		}

		public void PrepareTeleport()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			preTeleportPosition = GetTransformPosition();
		}

		public void FinishTeleport()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_005d: 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)
			if (!preTeleportPosition.HasValue)
			{
				MatchAnimationInstantly();
				return;
			}
			Vector3 transformPosition = GetTransformPosition();
			Vector3 val = transformPosition - preTeleportPosition.Value;
			targetAnimatedBoneSignal.FlattenSignal(Time.timeAsDouble, transformPosition);
			particleSignal.OffsetSignal(val);
			workingPosition += val;
		}

		private Vector3 ConstrainAngleBackward(Vector3 newPosition, float elasticity, float elasticitySoften)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_007a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0095: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (child == null || child.child == null)
			{
				return newPosition;
			}
			Vector3 val = child.child.currentFixedAnimatedBonePosition - child.currentFixedAnimatedBonePosition;
			Vector3 val2 = child.child.workingPosition - child.workingPosition;
			Quaternion val3 = Quaternion.FromToRotation(val, val2);
			Vector3 val4 = newPosition - child.workingPosition;
			Vector3 val5 = val3 * val4;
			Debug.DrawLine(newPosition, child.workingPosition + val5, Color.cyan);
			float num = Vector3.Distance(newPosition, child.workingPosition + val5);
			num /= child.GetLengthToParent();
			num = Mathf.Clamp01(num);
			num = Mathf.Pow(num, elasticitySoften * 2f);
			return Vector3.Lerp(newPosition, child.workingPosition + val5, elasticity * num);
		}

		private Vector3 ConstrainAngle(Vector3 newPosition, float elasticity, float elasticitySoften)
		{
			//IL_0020: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTransform && projectionAmount == 0f)
			{
				return newPosition;
			}
			Vector3 val;
			Vector3 val2;
			if (parent.parent == null)
			{
				val = parent.currentFixedAnimatedBonePosition + (parent.currentFixedAnimatedBonePosition - currentFixedAnimatedBonePosition);
				val2 = val;
			}
			else
			{
				val2 = parent.parent.workingPosition;
				val = parent.parent.currentFixedAnimatedBonePosition;
			}
			Vector3 val3 = parent.currentFixedAnimatedBonePosition - val;
			Vector3 val4 = parent.workingPosition - val2;
			Quaternion val5 = Quaternion.FromToRotation(val3, val4);
			Vector3 val6 = currentFixedAnimatedBonePosition - val;
			Vector3 val7 = val5 * val6;
			float num = Vector3.Distance(newPosition, val2 + val7);
			num /= GetLengthToParent();
			num = Mathf.Clamp01(num);
			num = Mathf.Pow(num, elasticitySoften * 2f);
			return Vector3.Lerp(newPosition, val2 + val7, elasticity * num);
		}

		public static Vector3 NextPhysicsPosition(Vector3 newPosition, Vector3 previousPosition, Vector3 localSpaceVelocity, float deltaTime, float gravityMultiplier, float friction, float airFriction)
		{
			//IL_0005: 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_0007: 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)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = deltaTime * deltaTime;
			Vector3 val = newPosition - previousPosition - localSpaceVelocity;
			return newPosition + val * (1f - airFriction) + localSpaceVelocity * (1f - friction) + Physics.gravity * (gravityMultiplier * num);
		}

		public void DebugDraw(Color simulateColor, Color targetColor, bool interpolated)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0027: 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_0063: 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)
			if (parent != null)
			{
				if (interpolated)
				{
					Debug.DrawLine(extrapolatedPosition, parent.extrapolatedPosition, simulateColor, 0f, false);
				}
				else
				{
					Debug.DrawLine(workingPosition, parent.workingPosition, simulateColor, 0f, false);
				}
				Debug.DrawLine(currentFixedAnimatedBonePosition, parent.currentFixedAnimatedBonePosition, targetColor, 0f, false);
			}
		}

		public Vector3 DeriveFinalSolvePosition(Vector3 offset)
		{
			//IL_0002: 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)
			//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)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			extrapolatedPosition = offset + particleSignal.SamplePosition(Time.timeAsDouble);
			return extrapolatedPosition;
		}

		public Vector3 GetCachedSolvePosition()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return extrapolatedPosition;
		}

		public void PrepareBone()
		{
			//IL_000d: 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)
			//IL_003b: 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_002e: 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)
			if (hasTransform)
			{
				if (boneRotationChangeCheck == transform.localRotation)
				{
					transform.localRotation = lastValidPoseBoneRotation;
				}
				if (bonePositionChangeCheck == transform.localPosition)
				{
					transform.localPosition = lastValidPoseBoneLocalPosition;
				}
			}
			CacheAnimationPosition();
		}

		public void OnDrawGizmos(JiggleSettingsBase jiggleSettings)
		{
			//IL_0036: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			if ((Object)(object)transform != (Object)null && child != null && (Object)(object)child.transform != (Object)null)
			{
				Gizmos.DrawLine(transform.position, child.transform.position);
			}
			if ((Object)(object)transform != (Object)null && child != null && (Object)(object)child.transform == (Object)null)
			{
				Gizmos.DrawLine(transform.position, child.GetProjectedPosition());
			}
			if ((Object)(object)transform != (Object)null && (Object)(object)jiggleSettings != (Object)null)
			{
				Gizmos.DrawWireSphere(transform.position, jiggleSettings.GetRadius(normalizedIndex));
			}
			if ((Object)(object)transform == (Object)null && (Object)(object)jiggleSettings != (Object)null)
			{
				Gizmos.DrawWireSphere(GetProjectedPosition(), jiggleSettings.GetRadius(normalizedIndex));
			}
		}

		public void PoseBone(float blend)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (child != null)
			{
				Vector3 val = Vector3.Lerp(targetAnimatedBoneSignal.SamplePosition(Time.timeAsDouble), extrapolatedPosition, blend);
				Vector3 val2 = Vector3.Lerp(child.targetAnimatedBoneSignal.SamplePosition(Time.timeAsDouble), child.extrapolatedPosition, blend);
				if (parent != null)
				{
					transform.position = val;
				}
				Vector3 transformPosition = child.GetTransformPosition();
				Vector3 val3 = transformPosition - transform.position;
				Vector3 val4 = val2 - val;
				Quaternion val5 = Quaternion.FromToRotation(val3, val4);
				transform.rotation = val5 * transform.rotation;
			}
			if (hasTransform)
			{
				boneRotationChangeCheck = transform.localRotation;
				bonePositionChangeCheck = transform.localPosition;
			}
		}
	}
	[DefaultExecutionOrder(200)]
	public class JiggleRigBuilder : MonoBehaviour
	{
		[SerializeField]
		[Tooltip("The root bone from which an individual JiggleRig will be constructed. The JiggleRig encompasses all children of the specified root.")]
		[FormerlySerializedAs("target")]
		private Transform rootTransform;

		[Tooltip("The settings that the rig should update with, create them using the Create->JigglePhysics->Settings menu option.")]
		public JiggleSettingsBase jiggleSettings;

		[SerializeField]
		[Tooltip("The list of transforms to ignore during the jiggle. Each bone listed will also ignore all the children of the specified bone.")]
		private List<Transform> ignoredTransforms;

		public List<Collider> colliders;

		[Tooltip("An air force that is applied to the entire rig, this is useful to plug in some wind volumes from external sources.")]
		public Vector3 wind;

		[Tooltip("Level of detail manager. This system will control how the jiggle rig saves performance cost.")]
		public JiggleRigLOD levelOfDetail;

		[Tooltip("Draws some simple lines to show what the simulation is doing. Generally this should be disabled.")]
		[SerializeField]
		private bool debugDraw;

		private JiggleSettingsData data;

		private bool initialized;

		[HideInInspector]
		protected List<JiggleBone> simulatedPoints;

		private double accumulation;

		private bool dirtyFromEnable = false;

		private bool wasLODActive = true;

		public static float maxCatchupTime => Time.fixedDeltaTime * 4f;

		private bool NeedsCollisions => colliders.Count != 0;

		public Transform GetRootTransform()
		{
			return rootTransform;
		}

		public void PrepareBone(Vector3 position, JiggleRigLOD jiggleRigLOD)
		{
			//IL_0014: 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)
			if (!initialized)
			{
				throw new UnityException("JiggleRig was never initialized. Please call JiggleRig.Initialize() if you're going to manually timestep.");
			}
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PrepareBone();
			}
			data = jiggleSettings.GetData();
			data = (((Object)(object)jiggleRigLOD != (Object)null) ? jiggleRigLOD.AdjustJiggleSettingsData(position, data) : data);
		}

		public void MatchAnimationInstantly()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.MatchAnimationInstantly();
			}
		}

		public void UpdateJiggle(Vector3 wind, double time)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.VerletPass(data, wind, time);
			}
			if (NeedsCollisions)
			{
				for (int num = simulatedPoints.Count - 1; num >= 0; num--)
				{
					simulatedPoints[num].CollisionPreparePass(data);
				}
			}
			foreach (JiggleBone simulatedPoint2 in simulatedPoints)
			{
				simulatedPoint2.ConstraintPass(data);
			}
			if (NeedsCollisions)
			{
				foreach (JiggleBone simulatedPoint3 in simulatedPoints)
				{
					simulatedPoint3.CollisionPass(jiggleSettings, colliders);
				}
			}
			foreach (JiggleBone simulatedPoint4 in simulatedPoints)
			{
				simulatedPoint4.SignalWritePosition(time);
			}
		}

		public void DeriveFinalSolve()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = simulatedPoints[0].DeriveFinalSolvePosition(Vector3.zero);
			Vector3 offset = simulatedPoints[0].transform.position - val;
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.DeriveFinalSolvePosition(offset);
			}
		}

		public void Pose(bool debugDraw)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			DeriveFinalSolve();
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PoseBone(data.blend);
				if (debugDraw)
				{
					simulatedPoint.DebugDraw(Color.red, Color.blue, interpolated: true);
				}
			}
		}

		public void PrepareTeleport()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.PrepareTeleport();
			}
		}

		public void FinishTeleport()
		{
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.FinishTeleport();
			}
		}

		protected virtual void CreateSimulatedPoints(ICollection<JiggleBone> outputPoints, ICollection<Transform> ignoredTransforms, Transform currentTransform, JiggleBone parentJiggleBone)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			JiggleBone jiggleBone = new JiggleBone(currentTransform, parentJiggleBone);
			outputPoints.Add(jiggleBone);
			if (currentTransform.childCount == 0)
			{
				if (jiggleBone.parent == null)
				{
					if ((Object)(object)jiggleBone.transform.parent == (Object)null)
					{
						throw new UnityException("Can't have a singular jiggle bone with no parents. That doesn't even make sense!");
					}
					outputPoints.Add(new JiggleBone(null, jiggleBone));
				}
				else
				{
					outputPoints.Add(new JiggleBone(null, jiggleBone));
				}
				return;
			}
			for (int i = 0; i < currentTransform.childCount; i++)
			{
				if (!ignoredTransforms.Contains(currentTransform.GetChild(i)))
				{
					CreateSimulatedPoints(outputPoints, ignoredTransforms, currentTransform.GetChild(i), jiggleBone);
				}
			}
		}

		private void Awake()
		{
			Initialize();
		}

		private void OnEnable()
		{
			JiggleRigHandler.AddBuilder(this);
			dirtyFromEnable = true;
		}

		private void OnDisable()
		{
			JiggleRigHandler.RemoveBuilder(this);
			PrepareTeleport();
		}

		public void Initialize()
		{
			accumulation = 0.0;
			simulatedPoints = new List<JiggleBone>();
			if ((Object)(object)rootTransform == (Object)null)
			{
				return;
			}
			CreateSimulatedPoints(simulatedPoints, ignoredTransforms, rootTransform, null);
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.CalculateNormalizedIndex();
			}
			initialized = true;
		}

		public virtual void Advance(float deltaTime)
		{
			//IL_001b: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)levelOfDetail != (Object)null && !levelOfDetail.CheckActive(((Component)this).transform.position))
			{
				if (wasLODActive)
				{
					PrepareTeleport();
				}
				wasLODActive = false;
				return;
			}
			if (!wasLODActive)
			{
				FinishTeleport();
			}
			PrepareBone(((Component)this).transform.position, levelOfDetail);
			if (dirtyFromEnable)
			{
				FinishTeleport();
				dirtyFromEnable = false;
			}
			accumulation = Math.Min(accumulation + (double)deltaTime, maxCatchupTime);
			while (accumulation > (double)Time.fixedDeltaTime)
			{
				accumulation -= Time.fixedDeltaTime;
				double time = Time.timeAsDouble - accumulation;
				UpdateJiggle(wind, time);
			}
			Pose(debugDraw);
			wasLODActive = true;
		}

		private void OnDrawGizmos()
		{
			if (!initialized || simulatedPoints == null)
			{
				Initialize();
			}
			foreach (JiggleBone simulatedPoint in simulatedPoints)
			{
				simulatedPoint.OnDrawGizmos(jiggleSettings);
			}
		}

		private void OnValidate()
		{
			if ((Object)(object)rootTransform == (Object)null)
			{
				rootTransform = ((Component)this).transform;
			}
			if (!Application.isPlaying)
			{
				Initialize();
			}
		}
	}
	public static class JiggleRigHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UpdateFunction <0>__UpdateJiggleRigs;
		}

		private static bool initialized = false;

		private static HashSet<JiggleRigBuilder> builders = new HashSet<JiggleRigBuilder>();

		private static void Initialize()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			if (!initialized)
			{
				PlayerLoopSystem currentPlayerLoop = PlayerLoop.GetCurrentPlayerLoop();
				PlayerLoopSystem self = currentPlayerLoop;
				PlayerLoopSystem systemToInject = default(PlayerLoopSystem);
				object obj = <>O.<0>__UpdateJiggleRigs;
				if (obj == null)
				{
					UpdateFunction val = UpdateJiggleRigs;
					<>O.<0>__UpdateJiggleRigs = val;
					obj = (object)val;
				}
				systemToInject.updateDelegate = (UpdateFunction)obj;
				systemToInject.type = typeof(JiggleRigHandler);
				currentPlayerLoop = self.InjectAt<PostLateUpdate>(systemToInject);
				PlayerLoop.SetPlayerLoop(currentPlayerLoop);
				initialized = true;
			}
		}

		private static void UpdateJiggleRigs()
		{
			CachedSphereCollider.StartPass();
			foreach (JiggleRigBuilder builder in builders)
			{
				builder.Advance(Time.deltaTime);
			}
			CachedSphereCollider.FinishedPass();
		}

		public static void AddBuilder(JiggleRigBuilder builder)
		{
			builders.Add(builder);
			Initialize();
		}

		public static void RemoveBuilder(JiggleRigBuilder builder)
		{
			builders.Remove(builder);
		}

		private static PlayerLoopSystem InjectAt<T>(this PlayerLoopSystem self, PlayerLoopSystem systemToInject)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			int num = FindIndexOfSubsystem<T>(self.subSystemList);
			if (num == -1)
			{
				throw new UnityException($"Failed to find PlayerLoopSystem with type{typeof(T)}");
			}
			List<PlayerLoopSystem> list = new List<PlayerLoopSystem>(self.subSystemList[num].subSystemList);
			foreach (PlayerLoopSystem item2 in list)
			{
				if (item2.type != typeof(JiggleRigBuilder))
				{
					continue;
				}
				Debug.LogWarning((object)$"Tried to inject a PlayerLoopSystem ({systemToInject.type}) more than once! Ignoring the second injection.");
				return self;
			}
			PlayerLoopSystem item = default(PlayerLoopSystem);
			object obj = <>O.<0>__UpdateJiggleRigs;
			if (obj == null)
			{
				UpdateFunction val = UpdateJiggleRigs;
				<>O.<0>__UpdateJiggleRigs = val;
				obj = (object)val;
			}
			item.updateDelegate = (UpdateFunction)obj;
			item.type = typeof(JiggleRigHandler);
			list.Insert(0, item);
			self.subSystemList[num].subSystemList = list.ToArray();
			return self;
		}

		private static int FindIndexOfSubsystem<T>(PlayerLoopSystem[] list, int index = -1)
		{
			if (list == null)
			{
				return -1;
			}
			for (int i = 0; i < list.Length; i++)
			{
				if (list[i].type == typeof(T))
				{
					return i;
				}
			}
			return -1;
		}
	}
	public abstract class JiggleRigLOD : ScriptableObject
	{
		public abstract bool CheckActive(Vector3 position);

		public abstract JiggleSettingsData AdjustJiggleSettingsData(Vector3 position, JiggleSettingsData data);
	}
	[CreateAssetMenu(fileName = "JiggleRigSimpleLOD", menuName = "JigglePhysics/JiggleRigSimpleLOD", order = 1)]
	public class JiggleRigSimpleLOD : JiggleRigLOD
	{
		[Tooltip("Distance to disable the jiggle rig")]
		[SerializeField]
		private float distance;

		[Tooltip("Level of detail manager. This system will control how the jiggle rig saves performance cost.")]
		[SerializeField]
		private float blend;

		[NonSerialized]
		private Camera currentCamera;

		[NonSerialized]
		private Transform cameraTransform;

		private bool TryGetCamera(out Camera camera)
		{
			if ((Object)(object)currentCamera == (Object)null || !((Component)currentCamera).CompareTag("MainCamera"))
			{
				currentCamera = Camera.main;
			}
			camera = currentCamera;
			return (Object)(object)currentCamera != (Object)null;
		}

		public override bool CheckActive(Vector3 position)
		{
			//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)
			if (!TryGetCamera(out var camera))
			{
				return false;
			}
			return Vector3.Distance(((Component)camera).transform.position, position) < distance;
		}

		public override JiggleSettingsData AdjustJiggleSettingsData(Vector3 position, JiggleSettingsData data)
		{
			//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)
			if (!TryGetCamera(out var camera))
			{
				return data;
			}
			float num = (Vector3.Distance(((Component)camera).transform.position, position) - distance + blend) / blend;
			num = Mathf.Clamp01(1f - num);
			data.blend = num;
			return data;
		}
	}
	public struct JiggleSettingsData
	{
		public float gravityMultiplier;

		public float friction;

		public float angleElasticity;

		public float blend;

		public float airDrag;

		public float lengthElasticity;

		public float elasticitySoften;

		public float radiusMultiplier;

		public static JiggleSettingsData Lerp(JiggleSettingsData a, JiggleSettingsData b, float t)
		{
			JiggleSettingsData result = default(JiggleSettingsData);
			result.gravityMultiplier = Mathf.Lerp(a.gravityMultiplier, b.gravityMultiplier, t);
			result.friction = Mathf.Lerp(a.friction, b.friction, t);
			result.angleElasticity = Mathf.Lerp(a.angleElasticity, b.angleElasticity, t);
			result.blend = Mathf.Lerp(a.blend, b.blend, t);
			result.airDrag = Mathf.Lerp(a.airDrag, b.airDrag, t);
			result.lengthElasticity = Mathf.Lerp(a.lengthElasticity, b.lengthElasticity, t);
			result.elasticitySoften = Mathf.Lerp(a.elasticitySoften, b.elasticitySoften, t);
			result.radiusMultiplier = Mathf.Lerp(a.radiusMultiplier, b.radiusMultiplier, t);
			return result;
		}
	}
	[CreateAssetMenu(fileName = "JiggleSettings", menuName = "JigglePhysics/Settings", order = 1)]
	public class JiggleSettings : JiggleSettingsBase
	{
		[SerializeField]
		[Range(0f, 2f)]
		[Tooltip("How much gravity to apply to the simulation, it is a multiplier of the Physics.gravity setting.")]
		private float gravityMultiplier = 1f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much mechanical friction to apply, this is specifically how quickly oscillations come to rest.")]
		private float friction = 0.4f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much angular force is applied to bring it to the target shape.")]
		private float angleElasticity = 0.4f;

		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much of the simulation should be expressed. A value of 0 would make the jiggle have zero effect. A value of 1 gives the full movement as intended. 0.5 would ")]
		private float blend = 1f;

		[FormerlySerializedAs("airFriction")]
		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much jiggled objects should get dragged behind by moving through the air. Or how \"thick\" the air is.")]
		private float airDrag = 0.1f;

		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How rigidly the rig holds its length. Low values cause lots of squash and stretch!")]
		private float lengthElasticity = 0.8f;

		[HideInInspector]
		[SerializeField]
		[Range(0f, 1f)]
		[Tooltip("How much to allow free bone motion before engaging elasticity.")]
		private float elasticitySoften = 0f;

		[HideInInspector]
		[SerializeField]
		[Tooltip("How much radius points have, only used for collisions. Set to 0 to disable collisions")]
		private float radiusMultiplier = 0f;

		[HideInInspector]
		[SerializeField]
		[Tooltip("How the radius is expressed as a curve along the bone chain from root to child.")]
		private AnimationCurve radiusCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 1f),
			new Keyframe(1f, 0f)
		});

		public override JiggleSettingsData GetData()
		{
			JiggleSettingsData result = default(JiggleSettingsData);
			result.gravityMultiplier = gravityMultiplier;
			result.friction = friction;
			result.airDrag = airDrag;
			result.blend = blend;
			result.angleElasticity = angleElasticity;
			result.elasticitySoften = elasticitySoften;
			result.lengthElasticity = lengthElasticity;
			result.radiusMultiplier = radiusMultiplier;
			return result;
		}

		public void SetData(JiggleSettingsData data)
		{
			gravityMultiplier = data.gravityMultiplier;
			friction = data.friction;
			angleElasticity = data.angleElasticity;
			blend = data.blend;
			airDrag = data.airDrag;
			lengthElasticity = data.lengthElasticity;
			elasticitySoften = data.elasticitySoften;
			radiusMultiplier = data.radiusMultiplier;
		}

		public override float GetRadius(float normalizedIndex)
		{
			return radiusMultiplier * radiusCurve.Evaluate(normalizedIndex);
		}

		public void SetRadiusCurve(AnimationCurve curve)
		{
			radiusCurve = curve;
		}
	}
	public class JiggleSettingsBase : ScriptableObject
	{
		public virtual JiggleSettingsData GetData()
		{
			return default(JiggleSettingsData);
		}

		public virtual float GetRadius(float normalizedIndex)
		{
			return 0f;
		}
	}
	[CreateAssetMenu(fileName = "JiggleSettingsBlend", menuName = "JigglePhysics/Blend Settings", order = 1)]
	public class JiggleSettingsBlend : JiggleSettingsBase
	{
		[Tooltip("The list of jiggle settings to blend between.")]
		public List<JiggleSettings> blendSettings;

		[Range(0f, 1f)]
		[Tooltip("A value from 0 to 1 that linearly blends between all of the blendSettings.")]
		public float normalizedBlend;

		public override JiggleSettingsData GetData()
		{
			int num = blendSettings.Count - 1;
			float num2 = Mathf.Clamp01(normalizedBlend);
			int num3 = Mathf.Clamp(Mathf.FloorToInt(num2 * (float)num), 0, num);
			int index = Mathf.Clamp(Mathf.FloorToInt(num2 * (float)num) + 1, 0, num);
			return JiggleSettingsData.Lerp(blendSettings[num3].GetData(), blendSettings[index].GetData(), Mathf.Clamp01(num2 * (float)num - (float)num3));
		}

		public override float GetRadius(float normalizedIndex)
		{
			float num = Mathf.Clamp01(normalizedBlend);
			int num2 = Mathf.FloorToInt(num * (float)blendSettings.Count);
			int num3 = Mathf.FloorToInt(num * (float)blendSettings.Count) + 1;
			return Mathf.Lerp(blendSettings[Mathf.Clamp(num2, 0, blendSettings.Count - 1)].GetRadius(normalizedIndex), blendSettings[Mathf.Clamp(num3, 0, blendSettings.Count - 1)].GetRadius(normalizedIndex), Mathf.Clamp01(num * (float)blendSettings.Count - (float)num2));
		}
	}
	public class PositionSignal
	{
		private struct Frame
		{
			public Vector3 position;

			public double time;
		}

		private Frame previousFrame;

		private Frame currentFrame;

		public PositionSignal(Vector3 startPosition, double time)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			currentFrame = (previousFrame = new Frame
			{
				position = startPosition,
				time = time
			});
		}

		public void SetPosition(Vector3 position, double time)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			previousFrame = currentFrame;
			currentFrame = new Frame
			{
				position = position,
				time = time
			};
		}

		public void OffsetSignal(Vector3 offset)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//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_0056: Unknown result type (might be due to invalid IL or missing references)
			previousFrame = new Frame
			{
				position = previousFrame.position + offset,
				time = previousFrame.time
			};
			currentFrame = new Frame
			{
				position = currentFrame.position + offset,
				time = previousFrame.time
			};
		}

		public void FlattenSignal(double time, Vector3 position)
		{
			//IL_000c: 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_0038: 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)
			previousFrame = new Frame
			{
				position = position,
				time = time - (double)(JiggleRigBuilder.maxCatchupTime * 2f)
			};
			currentFrame = new Frame
			{
				position = position,
				time = time - (double)JiggleRigBuilder.maxCatchupTime
			};
		}

		public Vector3 GetCurrent()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return currentFrame.position;
		}

		public Vector3 GetPrevious()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return previousFrame.position;
		}

		public Vector3 SamplePosition(double time)
		{
			//IL_0051: 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)
			//IL_0063: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			double num = currentFrame.time - previousFrame.time;
			if (num == 0.0)
			{
				return previousFrame.position;
			}
			double num2 = (time - previousFrame.time) / num;
			return Vector3.Lerp(previousFrame.position, currentFrame.position, (float)num2);
		}
	}
}
namespace ModelReplacement
{
	public static class PluginInfo
	{
		public const string GUID = "meow.ModelReplacementAPI";

		public const string NAME = "ModelReplacementAPI";

		public const string VERSION = "2.2.0";

		public const string WEBSITE = "https://github.com/BunyaPineTree/LethalCompany_ModelReplacementAPI";
	}
	[BepInPlugin("meow.ModelReplacementAPI", "ModelReplacementAPI", "2.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModelReplacementAPI : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerControllerB))]
		public class PlayerControllerBPatch
		{
			[HarmonyPatch("Update")]
			[HarmonyPostfix]
			public static void ManageRegistryBodyReplacements(ref PlayerControllerB __instance)
			{
				try
				{
					BodyReplacementBase component = ((Component)__instance.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
					if ((Object)(object)component != (Object)null && RegisteredModelReplacementExceptions.Contains(((object)component).GetType()))
					{
						return;
					}
					if (RegisteredModelReplacementOverride != null)
					{
						SetPlayerModelReplacement(__instance, RegisteredModelReplacementOverride);
						return;
					}
					int currentSuitID = __instance.currentSuitID;
					string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[currentSuitID].unlockableName;
					unlockableName = unlockableName.ToLower().Replace(" ", "");
					if (RegisteredModelReplacements.ContainsKey(unlockableName))
					{
						SetPlayerModelReplacement(__instance, RegisteredModelReplacements[unlockableName]);
					}
					else if (RegisteredModelReplacementDefault != null)
					{
						SetPlayerModelReplacement(__instance, RegisteredModelReplacementDefault);
					}
					else
					{
						RemovePlayerModelReplacement(__instance);
					}
				}
				catch (Exception ex)
				{
					Instance.Logger.LogWarning((object)ex);
				}
			}
		}

		public static bool moreCompanyPresent;

		public static bool thirdPersonPresent;

		public static bool LCthirdPersonPresent;

		public static bool mirrorDecorPresent;

		public static bool tooManyEmotesPresent;

		public static bool recordingCameraPresent;

		public static ModelReplacementAPI Instance;

		public ManualLogSource Logger;

		private static List<Type> RegisteredModelReplacementExceptions = new List<Type>();

		private static Dictionary<string, Type> RegisteredModelReplacements = new Dictionary<string, Type>();

		private static Type RegisteredModelReplacementOverride = null;

		private static Type RegisteredModelReplacementDefault = null;

		private static int steamLobbyID
		{
			get
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				int result;
				if (!GameNetworkManager.Instance.currentLobby.HasValue)
				{
					result = -1;
				}
				else
				{
					Lobby value = GameNetworkManager.Instance.currentLobby.Value;
					result = (int)((Lobby)(ref value)).Id.Value;
				}
				return result;
			}
		}

		public static bool isLan => steamLobbyID == -1;

		private void Awake()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			Logger = Logger.CreateLogSource("meow.ModelReplacementAPI");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			moreCompanyPresent = Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany");
			thirdPersonPresent = Chainloader.PluginInfos.ContainsKey("verity.3rdperson");
			LCthirdPersonPresent = Chainloader.PluginInfos.ContainsKey("LCThirdPerson");
			mirrorDecorPresent = Chainloader.PluginInfos.ContainsKey("quackandcheese.mirrordecor");
			tooManyEmotesPresent = Chainloader.PluginInfos.ContainsKey("FlipMods.TooManyEmotes");
			recordingCameraPresent = Chainloader.PluginInfos.ContainsKey("com.graze.gorillatag.placeablecamera");
			Harmony val = new Harmony("meow.ModelReplacementAPI");
			val.PatchAll();
			Logger.LogInfo((object)"Plugin meow.ModelReplacementAPI is loaded!");
		}

		public static void RegisterModelReplacementDefault(Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement default type {type}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacementOverride != null)
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement default, already registered to {RegisteredModelReplacementDefault}.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement default type {type}.");
			RegisteredModelReplacementDefault = type;
		}

		public static void RegisterModelReplacementOverride(Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement override type {type}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacementOverride != null)
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement override, already registered to {RegisteredModelReplacementOverride}.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement override type {type}.");
			RegisteredModelReplacementOverride = type;
		}

		public static void RegisterModelReplacementException(Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement exception type {type}, must inherit from BodyReplacementBase");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement exception type {type}.");
			if (!RegisteredModelReplacementExceptions.Contains(type))
			{
				RegisteredModelReplacementExceptions.Add(type);
			}
		}

		public static void RegisterSuitModelReplacement(string suitNameToReplace, Type type)
		{
			suitNameToReplace = suitNameToReplace.ToLower().Replace(" ", "");
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement type {type}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacements.ContainsKey(suitNameToReplace))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement type {type}, suit name to replace {suitNameToReplace} is already registered.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement type {type} to suit name {suitNameToReplace}.");
			RegisteredModelReplacements.Add(suitNameToReplace, type);
		}

		public static void SetPlayerModelReplacement(PlayerControllerB player, Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)("Cannot set body replacement of type " + type.Name + ", must inherit from BodyReplacementBase"));
			}
			else
			{
				if (!isLan && player.playerSteamId == 0)
				{
					return;
				}
				BodyReplacementBase component = ((Component)player.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
				int currentSuitID = player.currentSuitID;
				string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[currentSuitID].unlockableName;
				if ((Object)(object)component != (Object)null)
				{
					if (((object)component).GetType() == type)
					{
						if (!(component.suitName != unlockableName))
						{
							return;
						}
						Console.WriteLine($"Suit Change detected {component.suitName} => {unlockableName}, Replacing {type}.");
						Object.Destroy((Object)(object)component);
					}
					else
					{
						Console.WriteLine($"Model Replacement Change detected {((object)component).GetType()} => {type}, changing model.");
						Object.Destroy((Object)(object)component);
					}
				}
				BodyReplacementBase bodyReplacementBase = ((Component)player.thisPlayerBody).gameObject.AddComponent(type) as BodyReplacementBase;
				bodyReplacementBase.suitName = unlockableName;
			}
		}

		public static void RemovePlayerModelReplacement(PlayerControllerB player)
		{
			BodyReplacementBase component = ((Component)player.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Object.Destroy((Object)(object)component);
			}
		}
	}
	public abstract class BodyReplacementBase : MonoBehaviour
	{
		public ViewStateManager viewState = null;

		public MoreCompanyCosmeticManager cosmeticManager = null;

		public MaterialHelper materialHelper = null;

		public GameObject replacementModel;

		protected GameObject deadBody = null;

		protected GameObject replacementDeadBody = null;

		private MeshRenderer nameTagObj = null;

		private MeshRenderer nameTagObj2 = null;

		private int danceNumber = 0;

		private int previousDanceNumber = 0;

		public AvatarUpdater cosmeticAvatar = null;

		public bool UseNoPostProcessing = false;

		public bool DontConvertUnsupportedShaders = false;

		private bool emoteOngoing = false;

		public AvatarUpdater avatar { get; private set; }

		public PlayerControllerB controller { get; private set; }

		public AvatarUpdater ragdollAvatar { get; private set; }

		public string suitName { get; set; } = "";


		protected abstract GameObject LoadAssetsAndReturnModel();

		protected virtual void AddModelScripts()
		{
		}

		protected virtual AvatarUpdater GetAvatarUpdater()
		{
			return new AvatarUpdater();
		}

		protected internal virtual void OnHitEnemy(bool dead)
		{
			Console.WriteLine("PLAYER HIT ENEMY " + controller.playerUsername);
		}

		protected internal virtual void OnHitAlly(PlayerControllerB ally, bool dead)
		{
			Console.WriteLine("PLAYER HIT ALLY " + controller.playerUsername);
		}

		protected internal virtual void OnDamageTaken(bool dead)
		{
			Console.WriteLine("PLAYER TAKE DAMAGE  " + controller.playerUsername);
		}

		protected internal virtual void OnDamageTakenByAlly(PlayerControllerB ally, bool dead)
		{
			Console.WriteLine("PLAYER TAKE DAMAGE BY ALLY " + controller.playerUsername);
		}

		protected internal virtual void OnDeath()
		{
			Console.WriteLine("PLAYER DEATH " + controller.playerUsername + " ");
		}

		protected internal virtual void OnEmoteStart(int emoteId)
		{
			Console.WriteLine($"PLAYER EMOTE START {controller.playerUsername} ID {emoteId}");
		}

		protected internal virtual void OnEmoteEnd()
		{
			Console.WriteLine("PLAYER EMOTE END " + controller.playerUsername);
		}

		protected virtual void Awake()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: 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_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			controller = ((Component)this).GetComponent<PlayerControllerB>();
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Awake " + controller.playerUsername));
			replacementModel = LoadAssetsAndReturnModel();
			if ((Object)(object)replacementModel == (Object)null)
			{
				ModelReplacementAPI.Instance.Logger.LogFatal((object)"LoadAssetsAndReturnModel() returned null. Verify that your assetbundle works and your asset name is correct. ");
			}
			materialHelper = new MaterialHelper(this);
			Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
			Material sharedMaterial = ((Renderer)((Component)controller.thisPlayerModel).GetComponent<SkinnedMeshRenderer>()).sharedMaterial;
			sharedMaterial = new Material(sharedMaterial);
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Material> list = CollectionPool<List<Material>, Material>.Get();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				val.GetSharedMaterials(list);
				for (int j = 0; j < list.Count; j++)
				{
					Material val2 = list[j];
					if (!dictionary.TryGetValue(val2, out var value))
					{
						value = (dictionary[val2] = materialHelper.GetReplacementMaterial(sharedMaterial, val2));
					}
					list[j] = value;
				}
				val.SetMaterials(list);
			}
			CollectionPool<List<Material>, Material>.Release(list);
			SkinnedMeshRenderer[] componentsInChildren2 = replacementModel.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer val3 in componentsInChildren2)
			{
				val3.updateWhenOffscreen = true;
			}
			try
			{
				AddModelScripts();
			}
			catch (Exception ex)
			{
				ModelReplacementAPI.Instance.Logger.LogError((object)("Could not set all model scripts.\n Error: " + ex.Message));
			}
			replacementModel = Object.Instantiate<GameObject>(replacementModel);
			GameObject obj = replacementModel;
			((Object)obj).name = ((Object)obj).name + "(" + controller.playerUsername + ")";
			replacementModel.transform.localPosition = new Vector3(0f, 0f, 0f);
			replacementModel.SetActive(true);
			Bounds bounds = ((Renderer)controller.thisPlayerModel).bounds;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			float y = extents.y;
			bounds = GetBounds();
			float num = y / ((Bounds)(ref bounds)).extents.y;
			Transform transform = replacementModel.transform;
			transform.localScale *= num;
			avatar = GetAvatarUpdater();
			cosmeticAvatar = avatar;
			ragdollAvatar = new AvatarUpdater();
			avatar.AssignModelReplacement(((Component)controller).gameObject, replacementModel);
			viewState = new ViewStateManager(this);
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				cosmeticManager = new MoreCompanyCosmeticManager(this);
			}
			MeshRenderer[] componentsInChildren3 = ((Component)controller).gameObject.GetComponentsInChildren<MeshRenderer>();
			nameTagObj = componentsInChildren3.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "LevelSticker").First();
			nameTagObj2 = componentsInChildren3.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "BetaBadge").First();
			viewState.RendererPatches();
			SetAvatarRenderers(enabled: true);
			viewState.SetAllLayers();
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("AwakeEnd " + controller.playerUsername));
		}

		protected virtual void Start()
		{
			viewState.RendererPatches();
		}

		protected virtual void LateUpdate()
		{
			//IL_010f: 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)
			SetPlayerRenderers(enabled: false);
			viewState.SetAllLayers();
			GameObject val = null;
			try
			{
				val = ((Component)controller.deadBody).gameObject;
			}
			catch
			{
			}
			if (Object.op_Implicit((Object)(object)val) && (Object)(object)replacementDeadBody == (Object)null)
			{
				Console.WriteLine("Set cosmeticAvatar to ragdoll");
				cosmeticAvatar = ragdollAvatar;
				CreateAndParentRagdoll(controller.deadBody);
				OnDeath();
			}
			if (Object.op_Implicit((Object)(object)replacementDeadBody) && (Object)(object)val == (Object)null)
			{
				Console.WriteLine("Set cosmeticAvatar to living");
				cosmeticAvatar = avatar;
				Object.Destroy((Object)(object)replacementDeadBody);
				replacementDeadBody = null;
			}
			avatar.Update();
			ragdollAvatar.Update();
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				cosmeticManager.Update(useAvatarTransforms: true);
			}
			previousDanceNumber = danceNumber;
			AnimatorStateInfo currentAnimatorStateInfo = controller.playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
			int fullPathHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash;
			if (controller.performingEmote)
			{
				switch (fullPathHash)
				{
				case -462656950:
					danceNumber = 1;
					break;
				case 2103786480:
					danceNumber = 2;
					break;
				default:
					danceNumber = 3;
					break;
				}
			}
			else
			{
				danceNumber = 0;
			}
			if (ModelReplacementAPI.tooManyEmotesPresent)
			{
				danceNumber = SafeGetEmoteID(danceNumber);
			}
			if (danceNumber != previousDanceNumber)
			{
				if (previousDanceNumber == 0)
				{
					((MonoBehaviour)this).StartCoroutine(WaitForDanceNumberChange());
				}
				else if (danceNumber == 0)
				{
					OnEmoteEnd();
				}
				else if (!emoteOngoing)
				{
					OnEmoteStart(danceNumber);
				}
			}
		}

		protected virtual void OnDestroy()
		{
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Destroy body component for " + controller.playerUsername));
			SetPlayerRenderers(enabled: true);
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				cosmeticManager.Update(useAvatarTransforms: false);
			}
			Object.Destroy((Object)(object)replacementModel);
			Object.Destroy((Object)(object)replacementDeadBody);
		}

		private void CreateAndParentRagdoll(DeadBodyInfo bodyinfo)
		{
			deadBody = ((Component)bodyinfo).gameObject;
			SkinnedMeshRenderer componentInChildren = deadBody.GetComponentInChildren<SkinnedMeshRenderer>();
			replacementDeadBody = Object.Instantiate<GameObject>(replacementModel);
			GameObject obj = replacementDeadBody;
			((Object)obj).name = ((Object)obj).name + "(Ragdoll)";
			ragdollAvatar.AssignModelReplacement(deadBody, replacementDeadBody);
			Renderer[] componentsInChildren = replacementDeadBody.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = true;
				val.shadowCastingMode = (ShadowCastingMode)1;
				((Component)val).gameObject.layer = viewState.VisibleLayer;
			}
			((Renderer)componentInChildren).enabled = false;
			GameObject[] bodyBloodDecals = bodyinfo.bodyBloodDecals;
			foreach (GameObject val2 in bodyBloodDecals)
			{
				Transform parent = val2.transform.parent;
				Transform avatarTransformFromBoneName = ragdollAvatar.GetAvatarTransformFromBoneName(((Object)parent).name);
				if (Object.op_Implicit((Object)(object)avatarTransformFromBoneName))
				{
					Object.Instantiate<GameObject>(val2, avatarTransformFromBoneName);
				}
			}
		}

		private void SetAvatarRenderers(bool enabled)
		{
			Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = enabled;
			}
		}

		private void SetPlayerRenderers(bool enabled)
		{
			((Renderer)controller.thisPlayerModel).enabled = enabled;
			((Renderer)controller.thisPlayerModelLOD1).enabled = enabled;
			((Renderer)controller.thisPlayerModelLOD2).enabled = enabled;
			((Renderer)nameTagObj).enabled = enabled;
			((Renderer)nameTagObj2).enabled = enabled;
		}

		private Bounds GetBounds()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			IEnumerable<Bounds> source = from r in replacementModel.GetComponentsInChildren<SkinnedMeshRenderer>()
				select ((Renderer)r).bounds;
			Bounds val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.x).First();
			float x2 = ((Bounds)(ref val)).max.x;
			val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.y).First();
			float y = ((Bounds)(ref val)).max.y;
			val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.z).First();
			float z = ((Bounds)(ref val)).max.z;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.x).First();
			float x3 = ((Bounds)(ref val)).min.x;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.y).First();
			float y2 = ((Bounds)(ref val)).min.y;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.z).First();
			float z2 = ((Bounds)(ref val)).min.z;
			((Bounds)(ref result)).SetMinMax(new Vector3(x3, y2, z2), new Vector3(x2, y, z));
			return result;
		}

		private IEnumerator WaitForDanceNumberChange()
		{
			if (emoteOngoing)
			{
				yield break;
			}
			emoteOngoing = true;
			for (int frame = 0; frame < 20; frame++)
			{
				if (danceNumber == 0)
				{
					emoteOngoing = false;
					yield break;
				}
				yield return (object)new WaitForEndOfFrame();
			}
			if (danceNumber != 0)
			{
				emoteOngoing = false;
				OnEmoteStart(danceNumber);
			}
		}

		private int SafeGetEmoteID(int currentID)
		{
			return DangerousGetEmoteID(currentID);
		}

		private int DangerousGetEmoteID(int currentID)
		{
			UnlockableEmote currentlyPlayingEmote = PlayerPatcher.GetCurrentlyPlayingEmote(controller);
			if (currentlyPlayingEmote == null)
			{
				return currentID;
			}
			if (currentlyPlayingEmote.emoteId == 1)
			{
				return -1;
			}
			if (currentlyPlayingEmote.emoteId == 2)
			{
				return -2;
			}
			if (currentlyPlayingEmote.emoteId == 3)
			{
				return -3;
			}
			return currentlyPlayingEmote.emoteId;
		}
	}
}
namespace ModelReplacement.Patches
{
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
	internal class CosmeticPatch
	{
		private static void Postfix()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (!Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				return;
			}
			CosmeticApplication val = Object.FindObjectOfType<CosmeticApplication>();
			if (CosmeticRegistry.locallySelectedCosmetics.Count <= 0 || val.spawnedCosmetics.Count > 0)
			{
				return;
			}
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				val.ApplyCosmetic(locallySelectedCosmetic, true);
			}
			foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
				SetAllChildrenLayer(((Component)spawnedCosmetic).transform, 3);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, string layerName)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			int layer = LayerMask.NameToLayer(layerName);
			((Component)transform).gameObject.layer = layer;
			foreach (object item in transform)
			{
				SetAllChildrenLayer((Transform)item, layerName);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, int layer)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			((Component)transform).gameObject.layer = layer;
			foreach (object item in transform)
			{
				SetAllChildrenLayer((Transform)item, layer);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	public class EnemyAIPatch
	{
		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		[HarmonyAfter(new string[] { })]
		public static void HitEnemy(ref EnemyAI __instance, int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			if (!((Object)(object)playerWhoHit == (Object)null))
			{
				BodyReplacementBase component = ((Component)playerWhoHit.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.OnHitEnemy(__instance.isEnemyDead);
				}
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	public class MaskedPlayerEnemyPatch
	{
		[HarmonyPatch("SetSuit")]
		[HarmonyPrefix]
		public static void SetModelReplacement(ref MaskedPlayerEnemy __instance, int suitId)
		{
			BodyReplacementBase component = ((Component)__instance.mimickingPlayer.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
			if (!((Object)(object)component == (Object)null))
			{
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
	internal class PlayerPatch
	{
		[HarmonyPatch(typeof(PlayerControllerB))]
		public class PlayerControllerBPatch
		{
			[HarmonyPatch("DamagePlayerFromOtherClientClientRpc")]
			[HarmonyPrefix]
			public static void DamagePlayerFromOtherClientClientRpc(ref PlayerControllerB __instance, int damageAmount, Vector3 hitDirection, int playerWhoHit, int newHealthAmount)
			{
				PlayerControllerB val = __instance.playersManager.allPlayerScripts[playerWhoHit];
				if (!((Object)(object)val == (Object)null))
				{
					BodyReplacementBase component = ((Component)val.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.OnHitAlly(__instance, __instance.isPlayerDead);
					}
				}
			}

			[HarmonyPatch("DamagePlayerClientRpc")]
			[HarmonyPrefix]
			public static void DamagePlayerClientRpc(ref PlayerControllerB __instance, int damageNumber, int newHealthAmount)
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					BodyReplacementBase component = ((Component)__instance.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
					Console.WriteLine("PLAYER TAKE DAMAGE " + __instance.playerUsername);
					if (Object.op_Implicit((Object)(object)component))
					{
						component.OnDamageTaken(__instance.isPlayerDead);
					}
				}
			}
		}

		[HarmonyAfter(new string[] { "quackandcheese.mirrordecor" })]
		private static void Postfix(ref PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				PlayerControllerB val = __instance;
				((Renderer)val.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				((Component)val.thisPlayerModel).gameObject.layer = ViewStateManager.modelLayer;
				((Component)val.thisPlayerModelArms).gameObject.layer = ViewStateManager.armsLayer;
				val.gameplayCamera.cullingMask = ViewStateManager.CullingMaskFirstPerson;
			}
		}
	}
}
namespace ModelReplacement.Modules
{
	public class MaterialHelper
	{
		private BodyReplacementBase bodyReplacement;

		private static readonly string[] shaderPrefixWhitelist = new string[9] { "HDRP/", "GUI/", "Sprites/", "UI/", "Unlit/", "Toon", "lilToon", "Shader Graphs/", "Hidden/" };

		private bool DontConvertUnsupportedShaders => bodyReplacement.DontConvertUnsupportedShaders;

		public MaterialHelper(BodyReplacementBase bodyreplacement)
		{
			bodyReplacement = bodyreplacement;
		}

		public virtual Material GetReplacementMaterial(Material gameMaterial, Material modelMaterial)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (DontConvertUnsupportedShaders || shaderPrefixWhitelist.Any((string prefix) => ((Object)modelMaterial.shader).name.StartsWith(prefix)))
			{
				return modelMaterial;
			}
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Creating replacement material for material " + ((Object)modelMaterial).name + " / shader " + ((Object)modelMaterial.shader).name));
			Material val = new Material(gameMaterial);
			val.color = modelMaterial.color;
			val.mainTexture = modelMaterial.mainTexture;
			val.mainTextureOffset = modelMaterial.mainTextureOffset;
			val.mainTextureScale = modelMaterial.mainTextureScale;
			val.EnableKeyword("_EMISSION");
			val.EnableKeyword("_NORMALMAP");
			val.EnableKeyword("_SPECGLOSSMAP");
			val.SetFloat("_NormalScale", 0f);
			HDMaterial.ValidateMaterial(val);
			return val;
		}
	}
	public class MoreCompanyCosmeticManager
	{
		public enum CosmeticType2
		{
			HAT,
			WRIST,
			CHEST,
			R_LOWER_ARM,
			HIP,
			L_SHIN,
			R_SHIN
		}

		private BodyReplacementBase bodyReplacement;

		private PlayerControllerB controller;

		private GameObject replacementModel;

		private Dictionary<CosmeticType2, Transform> cosmeticTransformPairs = new Dictionary<CosmeticType2, Transform>();

		private AvatarUpdater cosmeticAvatar => bodyReplacement.cosmeticAvatar;

		public MoreCompanyCosmeticManager(BodyReplacementBase bodyreplacement)
		{
			bodyReplacement = bodyreplacement;
			controller = bodyreplacement.controller;
			replacementModel = bodyreplacement.replacementModel;
		}

		public void Update(bool useAvatarTransforms)
		{
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				SafeRenderCosmetics(useAvatarTransforms);
			}
		}

		private void SafeRenderCosmetics(bool useAvatarTransforms)
		{
			DangerousRenderCosmetics(useAvatarTransforms);
		}

		private void RefreshCosmetics()
		{
			if (cosmeticTransformPairs.Count == 0)
			{
				cosmeticTransformPairs.Add(CosmeticType2.HAT, cosmeticAvatar.GetAvatarTransformFromBoneName("spine.004"));
				cosmeticTransformPairs.Add(CosmeticType2.CHEST, cosmeticAvatar.GetAvatarTransformFromBoneName("spine.003"));
				cosmeticTransformPairs.Add(CosmeticType2.R_LOWER_ARM, cosmeticAvatar.GetAvatarTransformFromBoneName("arm.R_lower"));
				cosmeticTransformPairs.Add(CosmeticType2.HIP, cosmeticAvatar.GetAvatarTransformFromBoneName("spine"));
				cosmeticTransformPairs.Add(CosmeticType2.L_SHIN, cosmeticAvatar.GetAvatarTransformFromBoneName("shin.L"));
				cosmeticTransformPairs.Add(CosmeticType2.R_SHIN, cosmeticAvatar.GetAvatarTransformFromBoneName("shin.R"));
			}
		}

		private void DangerousRenderCosmetics(bool useAvatarTransforms)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected I4, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			RefreshCosmetics();
			CosmeticApplication componentInChildren = ((Component)controller).gameObject.GetComponentInChildren<CosmeticApplication>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			if (useAvatarTransforms)
			{
				foreach (CosmeticInstance spawnedCosmetic in componentInChildren.spawnedCosmetics)
				{
					Transform val = null;
					CosmeticType cosmeticType = spawnedCosmetic.cosmeticType;
					CosmeticType val2 = cosmeticType;
					switch ((int)val2)
					{
					case 0:
						val = cosmeticTransformPairs[CosmeticType2.HAT];
						break;
					case 2:
						val = cosmeticTransformPairs[CosmeticType2.CHEST];
						break;
					case 3:
						val = cosmeticTransformPairs[CosmeticType2.R_LOWER_ARM];
						break;
					case 4:
						val = cosmeticTransformPairs[CosmeticType2.HIP];
						break;
					case 5:
						val = cosmeticTransformPairs[CosmeticType2.L_SHIN];
						break;
					case 6:
						val = cosmeticTransformPairs[CosmeticType2.R_SHIN];
						break;
					}
					((Component)spawnedCosmetic).transform.parent = null;
					((Component)spawnedCosmetic).transform.SetPositionAndRotation(val.position, val.rotation);
				}
				return;
			}
			componentInChildren.RefreshAllCosmeticPositions();
		}
	}
	public enum ViewState
	{
		None,
		ThirdPerson,
		FirstPerson,
		Debug
	}
	public class ViewStateManager
	{
		private static int CullingMaskThirdPerson = 960174079;

		public static int CullingMaskFirstPerson = 1765480439;

		pr

BepInEx/plugins/PersistentPurchases.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements.Collections;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PersistentPurchases")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Keeps bought ship objects after failing to meet quota")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("PersistentPurchases")]
[assembly: AssemblyTitle("PersistentPurchases")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PersistentPurchases
{
	[HarmonyPatch]
	public class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPriority(-23)]
		public static void generateConfig()
		{
			Plugin.setupConfig(StartOfRound.Instance.unlockablesList.unlockables);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		public static void storeUnlocked(StartOfRound __instance, out List<Tuple<int, Vector3, Vector3>> __state)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			Plugin.log.LogInfo((object)"Taking note of bought unlockables");
			__state = new List<Tuple<int, Vector3, Vector3>>();
			List<UnlockableItem> unlockables = __instance.unlockablesList.unlockables;
			for (int i = 0; i < unlockables.Count; i++)
			{
				Plugin.log.LogDebug((object)$"{unlockables[i].unlockableName} - unlocked({unlockables[i].hasBeenUnlockedByPlayer}) - should persist({Plugin.unlockableConfig[i].Value})");
				if (unlockables[i].hasBeenUnlockedByPlayer && Plugin.unlockableConfig[i].Value)
				{
					__state.Add(Tuple.Create<int, Vector3, Vector3>(i, unlockables[i].placedPosition, unlockables[i].placedRotation));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		public static void loadUnlocked(StartOfRound __instance, List<Tuple<int, Vector3, Vector3>> __state)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			Plugin.log.LogInfo((object)"Rebuying unlockables");
			foreach (Tuple<int, Vector3, Vector3> item in __state)
			{
				Plugin.log.LogDebug((object)__instance.unlockablesList.unlockables[item.Item1].unlockableName);
				UnlockableItem val = __instance.unlockablesList.unlockables[item.Item1];
				__instance.BuyShipUnlockableServerRpc(item.Item1, TimeOfDay.Instance.quotaVariables.startingCredits);
				if (__instance.SpawnedShipUnlockables.ContainsKey(item.Item1))
				{
					NetworkObject component = DictionaryExtensions.Get<int, GameObject>((IDictionary<int, GameObject>)__instance.SpawnedShipUnlockables, item.Item1, (GameObject)null).GetComponent<NetworkObject>();
					if ((Object)(object)component != (Object)null)
					{
						ShipBuildModeManager.Instance.StoreObjectServerRpc(NetworkObjectReference.op_Implicit(component), 0);
					}
					else
					{
						Plugin.log.LogWarning((object)("Failed to find NetworkObject for " + val.unlockableName));
					}
				}
				else
				{
					Plugin.log.LogWarning((object)("SpawnedShipUnlockables did not contain " + val.unlockableName));
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
	public class RemoveUneccesaryAndAnnoyingReset
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			Plugin.log.LogInfo((object)"Beginning patching of GameNetworkManager.ResetSavedGameValues");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			bool flag = false;
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], typeof(GameNetworkManager).GetMethod("ResetUnlockablesListValues")))
				{
					flag = true;
					list[i - 1].opcode = OpCodes.Nop;
					list[i].opcode = OpCodes.Nop;
					list[i].operand = null;
					break;
				}
			}
			if (flag)
			{
				Plugin.log.LogInfo((object)"Patched GameNetworkManager.ResetSavedGameValues");
			}
			else
			{
				Plugin.log.LogError((object)"Failed to patch GameNetworkManager.ResetSavedGameValues!");
			}
			return list.AsEnumerable();
		}
	}
	[BepInPlugin("PersistentPurchases", "PersistentPurchases", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> placeUnlockables;

		public static ManualLogSource log = new ManualLogSource("PersistentPurchases");

		public static Harmony harmony = new Harmony("PersistentPurchases");

		public static string[] knownFurniture = new string[19]
		{
			"Cozy lights", "Television", "Cupboard", "File Cabinet", "Toilet", "Shower", "Light switch", "Record player", "Table", "Bunkbeds",
			"Terminal", "Romantic table", "JackOLantern", "Welcome mat", "Goldfish", "Plushie pajama man", "SmallRug", "LargeRug", "FatalitiesSign"
		};

		public static List<ConfigFile> despair = new List<ConfigFile>();

		public static List<ConfigEntry<bool>> unlockableConfig = new List<ConfigEntry<bool>>();

		private void Awake()
		{
			Logger.Sources.Add((ILogSource)(object)log);
			despair.Add(((BaseUnityPlugin)this).Config);
			harmony.PatchAll(typeof(Patches));
			harmony.PatchAll(typeof(RemoveUneccesaryAndAnnoyingReset));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin PersistentPurchases is loaded!");
		}

		public static void setupConfig(List<UnlockableItem> unlockables)
		{
			log.LogInfo((object)$"Registering {unlockables.Count} unlockables");
			for (int i = 0; i < unlockables.Count; i++)
			{
				log.LogDebug((object)(unlockables[i].unlockableName ?? ""));
				unlockableConfig.Add(despair[0].Bind<bool>("Unlockables", unlockables[i].unlockableName, unlockables[i].unlockableType == 0 || knownFurniture.Contains(unlockables[i].unlockableName), (ConfigDescription)null));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PersistentPurchases";

		public const string PLUGIN_NAME = "PersistentPurchases";

		public const string PLUGIN_VERSION = "1.1.1";
	}
}

BepInEx/plugins/MirrorDecor/MirrorDecor.dll

Decompiled 8 months ago
using System;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using MoreCompany.Cosmetics;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MirrorDecor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod for Lethal Company that adds a working mirror decoration that you can buy for your ship!")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyInformationalVersion("1.1.6")]
[assembly: AssemblyProduct("MirrorDecor")]
[assembly: AssemblyTitle("MirrorDecor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MirrorDecor
{
	public class Config
	{
		public static ConfigEntry<bool> mirrorEnabled;

		public static ConfigEntry<int> mirrorPrice;

		public static ConfigEntry<bool> alwaysAvailable;

		public static ConfigEntry<int> resolution;

		public static void Load()
		{
			mirrorEnabled = Plugin.config.Bind<bool>("Mirror", "MirrorEnabled", true, "Will you be able to purchase the mirror?");
			mirrorPrice = Plugin.config.Bind<int>("Mirror", "MirrorPrice", 100, "What will be the price of the mirror?");
			alwaysAvailable = Plugin.config.Bind<bool>("Mirror", "AlwaysAvailable", true, "Is the mirror always available to purchase from the store?");
			resolution = Plugin.config.Bind<int>("Mirror", "MirrorResolution", 2000, "What is the resolution/quality of the mirror image? (ex. 2000 = 2000x2000 pixels)");
		}
	}
	[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
	internal class CosmeticPatch
	{
		private static void Postfix()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				return;
			}
			CosmeticApplication val = Object.FindObjectOfType<CosmeticApplication>();
			if (CosmeticRegistry.locallySelectedCosmetics.Count <= 0 || val.spawnedCosmetics.Count > 0)
			{
				return;
			}
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				val.ApplyCosmetic(locallySelectedCosmetic, true);
			}
			foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
				SetAllChildrenLayer(((Component)spawnedCosmetic).transform, 23);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, string layerName)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			int layer = LayerMask.NameToLayer(layerName);
			((Component)transform).gameObject.layer = layer;
			foreach (Transform item in transform)
			{
				SetAllChildrenLayer(item, layerName);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, int layer)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			((Component)transform).gameObject.layer = layer;
			foreach (Transform item in transform)
			{
				SetAllChildrenLayer(item, layer);
			}
		}
	}
	public class CustomUnlockable
	{
		public string name = "";

		public string unlockablePath = "";

		public string infoPath = "";

		public Action<UnlockableItem> unlockableAction = delegate
		{
		};

		public bool enabled = true;

		public int unlockCost = -1;

		public CustomUnlockable(string name, string unlockablePath, string infoPath, Action<UnlockableItem> action = null, int unlockCost = -1)
		{
			this.name = name;
			this.unlockablePath = unlockablePath;
			this.infoPath = infoPath;
			if (action != null)
			{
				unlockableAction = action;
			}
			this.unlockCost = unlockCost;
		}

		public static CustomUnlockable Add(string name, string unlockablePath, string infoPath = null, Action<UnlockableItem> action = null, int unlockCost = -1, bool enabled = true)
		{
			return new CustomUnlockable(name, unlockablePath, infoPath, action, unlockCost)
			{
				enabled = enabled
			};
		}
	}
	public class MirrorScript : MonoBehaviour
	{
		private void Update()
		{
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
	internal class PlayerPatch
	{
		private static void Postfix(ref PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				PlayerControllerB obj = __instance;
				((Renderer)obj.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				((Component)obj.thisPlayerModel).gameObject.layer = 23;
				((Component)obj.thisPlayerModelArms).gameObject.layer = 5;
			}
		}
	}
	[BepInPlugin("quackandcheese.mirrordecor", "MirrorDecor", "1.1.6")]
	[BepInDependency("evaisa.lethallib", "0.3.1")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "quackandcheese.mirrordecor";

		public const string ModName = "MirrorDecor";

		public const string ModVersion = "1.1.6";

		public static AssetBundle Bundle;

		public static ConfigFile config;

		public static ManualLogSource logger;

		public static List<CustomUnlockable> customUnlockables;

		private void Awake()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			Bundle = QuickLoadAssetBundle("mirror.assets");
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			new Harmony("quackandcheese.mirrordecor").PatchAll();
			Config.Load();
			RegisterItems();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MirrorDecor is loaded!");
		}

		private void RegisterItems()
		{
			customUnlockables = new List<CustomUnlockable> { CustomUnlockable.Add("Mirror", "Assets/Mirror/Unlockables/Mirror/Mirror.asset", "Assets/Mirror/Unlockables/Mirror/MirrorInfo.asset", null, Config.mirrorPrice.Value, Config.mirrorEnabled.Value) };
			Bundle.LoadAsset<UnlockableItemDef>("Assets/Mirror/Unlockables/Mirror/Mirror.asset").unlockable.alwaysInStock = Config.alwaysAvailable.Value;
			RenderTexture renderTexture = Bundle.LoadAsset<RenderTexture>("Assets/Mirror/Materials/Mirror.renderTexture");
			int value = Config.resolution.Value;
			Resize(renderTexture, value, value);
			foreach (CustomUnlockable customUnlockable in customUnlockables)
			{
				if (customUnlockable.enabled)
				{
					UnlockableItem unlockable = Bundle.LoadAsset<UnlockableItemDef>(customUnlockable.unlockablePath).unlockable;
					if ((Object)(object)unlockable.prefabObject != (Object)null)
					{
						NetworkPrefabs.RegisterNetworkPrefab(unlockable.prefabObject);
					}
					TerminalNode val = null;
					if (customUnlockable.infoPath != null)
					{
						val = Bundle.LoadAsset<TerminalNode>(customUnlockable.infoPath);
					}
					Unlockables.RegisterUnlockable(unlockable, (StoreType)2, (TerminalNode)null, (TerminalNode)null, val, customUnlockable.unlockCost);
				}
			}
		}

		public static T FindAsset<T>(string name) where T : Object
		{
			return Resources.FindObjectsOfTypeAll<T>().ToList().Find((T x) => ((Object)x).name == name);
		}

		public static AssetBundle QuickLoadAssetBundle(string assetBundleName)
		{
			return AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assetBundleName));
		}

		private void Resize(RenderTexture renderTexture, int width, int height)
		{
			if (Object.op_Implicit((Object)(object)renderTexture))
			{
				renderTexture.Release();
				((Texture)renderTexture).width = width;
				((Texture)renderTexture).height = height;
			}
		}

		public void sendModInfo()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Value.Metadata.GUID.Contains("ModSync"))
				{
					try
					{
						List<string> list = new List<string> { "quackandcheese", "MirrorDecor" };
						((Component)pluginInfo.Value.Instance).BroadcastMessage("getModInfo", (object)list, (SendMessageOptions)1);
						break;
					}
					catch (Exception)
					{
						logger.LogInfo((object)"Failed to send info to ModSync, go yell at Minx");
						break;
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MirrorDecor";

		public const string PLUGIN_NAME = "MirrorDecor";

		public const string PLUGIN_VERSION = "1.1.6";
	}
}

BepInEx/plugins/LethalExpansion.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Adapters;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LethalExpansion.Extenders;
using LethalExpansion.Patches;
using LethalExpansion.Patches.Monsters;
using LethalExpansion.Utils;
using LethalExpansion.Utils.HUD;
using LethalSDK.Component;
using LethalSDK.ScriptableObjects;
using LethalSDK.Utils;
using TMPro;
using Unity.AI.Navigation;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalExpansion")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalExpansion")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f80eb3fd-9563-4f80-9fc7-3fcce1655c13")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AutoScrollText : MonoBehaviour
{
	public TextMeshProUGUI textMeshPro;

	public float scrollSpeed = 15f;

	private Vector2 startPosition;

	private float textHeight;

	private bool startScrolling = false;

	private bool isWaitingToReset = false;

	private float displayHeight;

	private float fontSize;

	private void Start()
	{
		textMeshPro = ((Component)this).GetComponent<TextMeshProUGUI>();
		InitializeScrolling();
	}

	private void InitializeScrolling()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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)
		if ((Object)(object)textMeshPro != (Object)null)
		{
			startPosition = ((TMP_Text)textMeshPro).rectTransform.anchoredPosition;
			textHeight = ((TMP_Text)textMeshPro).preferredHeight;
			displayHeight = ((TMP_Text)textMeshPro).rectTransform.sizeDelta.y;
			fontSize = ((TMP_Text)textMeshPro).fontSize;
		}
		((MonoBehaviour)this).StartCoroutine(WaitBeforeScrolling(5f));
	}

	private IEnumerator WaitBeforeScrolling(float waitTime)
	{
		yield return (object)new WaitForSeconds(waitTime);
		startScrolling = true;
	}

	private IEnumerator WaitBeforeResetting(float waitTime)
	{
		isWaitingToReset = true;
		yield return (object)new WaitForSeconds(waitTime);
		((TMP_Text)textMeshPro).rectTransform.anchoredPosition = startPosition;
		isWaitingToReset = false;
		((MonoBehaviour)this).StartCoroutine(WaitBeforeScrolling(5f));
	}

	private void Update()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)textMeshPro != (Object)null && startScrolling && !isWaitingToReset)
		{
			RectTransform rectTransform = ((TMP_Text)textMeshPro).rectTransform;
			rectTransform.anchoredPosition += new Vector2(0f, scrollSpeed * Time.deltaTime);
			if (((TMP_Text)textMeshPro).rectTransform.anchoredPosition.y >= startPosition.y + textHeight - displayHeight - fontSize)
			{
				startScrolling = false;
				((MonoBehaviour)this).StartCoroutine(WaitBeforeResetting(5f));
			}
		}
	}

	public void ResetScrolling()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		((MonoBehaviour)this).StopAllCoroutines();
		if ((Object)(object)textMeshPro != (Object)null)
		{
			((TMP_Text)textMeshPro).rectTransform.anchoredPosition = startPosition;
		}
		isWaitingToReset = false;
		InitializeScrolling();
	}
}
public class TooltipHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
	private string description;

	private string netinfo;

	public static RectTransform ModSettingsToolTipPanel;

	public static TMP_Text ModSettingsToolTipPanelDescription;

	public static TMP_Text ModSettingsToolTipPanelNetInfo;

	public int index;

	private float delay = 0.5f;

	private bool isPointerOver = false;

	public void OnPointerEnter(PointerEventData eventData)
	{
		isPointerOver = true;
		((MonoBehaviour)this).StartCoroutine(ShowTooltipAfterDelay());
	}

	public void OnPointerExit(PointerEventData eventData)
	{
		isPointerOver = false;
		((Component)ModSettingsToolTipPanel).gameObject.SetActive(false);
	}

	private IEnumerator ShowTooltipAfterDelay()
	{
		yield return (object)new WaitForSeconds(delay);
		if (isPointerOver)
		{
			ModSettingsToolTipPanel.anchoredPosition = new Vector2(-30f, ((Component)this).GetComponent<RectTransform>().anchoredPosition.y + -80f);
			description = ConfigManager.Instance.FindDescription(index);
			(bool, bool) info = ConfigManager.Instance.FindNetInfo(index);
			netinfo = "Network synchronization: " + (info.Item1 ? "Yes" : "No") + "\nMod required by clients: " + (info.Item2 ? "No" : "Yes");
			ModSettingsToolTipPanelDescription.text = description;
			ModSettingsToolTipPanelNetInfo.text = netinfo;
			((Component)ModSettingsToolTipPanel).gameObject.SetActive(true);
		}
	}
}
public class ConfigItem
{
	public string Key { get; set; }

	public Type type { get; set; }

	public object Value { get; set; }

	public object DefaultValue { get; set; }

	public string Tab { get; set; }

	public string Description { get; set; }

	public object MinValue { get; set; }

	public object MaxValue { get; set; }

	public bool Sync { get; set; }

	public bool Hidden { get; set; }

	public bool Optional { get; set; }

	public bool RequireRestart { get; set; }

	public ConfigItem(string key, object defaultValue, string tab, string description, object minValue = null, object maxValue = null, bool sync = true, bool optional = false, bool hidden = false, bool requireRestart = false)
	{
		Key = key;
		DefaultValue = defaultValue;
		type = defaultValue.GetType();
		Tab = tab;
		Description = description;
		if (minValue != null && maxValue != null)
		{
			if (minValue.GetType() == type && maxValue.GetType() == type)
			{
				MinValue = minValue;
				MaxValue = maxValue;
			}
		}
		else
		{
			MinValue = null;
			MaxValue = null;
		}
		Sync = sync;
		Optional = optional;
		Hidden = hidden;
		Value = DefaultValue;
		RequireRestart = requireRestart;
	}
}
namespace LethalExpansion
{
	[BepInPlugin("LethalExpansion", "LethalExpansion", "1.3.11")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LethalExpansion : BaseUnityPlugin
	{
		private enum compatibility
		{
			unknown,
			perfect,
			good,
			medium,
			bad,
			critical
		}

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

			public static Func<PluginInfo, bool> <>9__32_1;

			public static UnityAction <>9__32_0;

			public static Func<PluginInfo, bool> <>9__32_2;

			public static Func<PluginInfo, bool> <>9__32_3;

			public static Func<AudioMixerGroup, bool> <>9__33_0;

			public static Func<GameObject, bool> <>9__33_1;

			public static Func<AudioMixerGroup, bool> <>9__33_2;

			public static Func<AudioMixerGroup, bool> <>9__33_3;

			public static Func<AudioMixerGroup, bool> <>9__33_4;

			public static Func<PluginInfo, bool> <>9__36_2;

			public static Func<PluginInfo, bool> <>9__36_0;

			public static Func<PluginInfo, bool> <>9__36_1;

			internal bool <OnSceneLoaded>b__32_1(PluginInfo p)
			{
				return p.Metadata.GUID == "CoomfyDungeon";
			}

			internal void <OnSceneLoaded>b__32_0()
			{
				ConfigManager.Instance.SetItemValue("CoomfyDungeonCompatibility", value: true);
				ConfigManager.Instance.SetEntryValue("CoomfyDungeonCompatibility", value: true);
			}

			internal bool <OnSceneLoaded>b__32_2(PluginInfo p)
			{
				return p.Metadata.GUID == "BiggerLobby";
			}

			internal bool <OnSceneLoaded>b__32_3(PluginInfo p)
			{
				return p.Metadata.GUID == "KoderTech.BoomboxController";
			}

			internal bool <LoadCustomMoon>b__33_0(AudioMixerGroup a)
			{
				return ((Object)a).name == "Master";
			}

			internal bool <LoadCustomMoon>b__33_1(GameObject o)
			{
				//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)
				Scene scene = o.scene;
				return ((Scene)(ref scene)).name != "InitSceneLaunchOptions";
			}

			internal bool <LoadCustomMoon>b__33_2(AudioMixerGroup a)
			{
				return ((Object)a).name == "Master";
			}

			internal bool <LoadCustomMoon>b__33_3(AudioMixerGroup a)
			{
				return ((Object)a).name == "Master";
			}

			internal bool <LoadCustomMoon>b__33_4(AudioMixerGroup a)
			{
				return ((Object)a).name == "Master";
			}

			internal bool <waitForSession>b__36_2(PluginInfo p)
			{
				return p.Metadata.GUID == "BrutalCompanyPlus";
			}

			internal bool <waitForSession>b__36_0(PluginInfo p)
			{
				return p.Metadata.GUID == "LethalAdjustments";
			}

			internal bool <waitForSession>b__36_1(PluginInfo p)
			{
				return p.Metadata.GUID == "CoomfyDungeon";
			}
		}

		private const string PluginGUID = "LethalExpansion";

		private const string PluginName = "LethalExpansion";

		private const string VersionString = "1.3.11";

		public static readonly Version ModVersion = new Version("1.3.11");

		private readonly Version[] CompatibleModVersions = new Version[1]
		{
			new Version(1, 3, 11)
		};

		private readonly Dictionary<string, compatibility> CompatibleMods = new Dictionary<string, compatibility>
		{
			{
				"com.sinai.unityexplorer",
				compatibility.medium
			},
			{
				"HDLethalCompany",
				compatibility.good
			},
			{
				"LC_API",
				compatibility.good
			},
			{
				"me.swipez.melonloader.morecompany",
				compatibility.medium
			},
			{
				"BrutalCompanyPlus",
				compatibility.medium
			},
			{
				"MoonOfTheDay",
				compatibility.good
			},
			{
				"Television_Controller",
				compatibility.bad
			},
			{
				"beeisyou.LandmineFix",
				compatibility.perfect
			},
			{
				"LethalAdjustments",
				compatibility.good
			},
			{
				"CoomfyDungeon",
				compatibility.bad
			},
			{
				"BiggerLobby",
				compatibility.critical
			},
			{
				"KoderTech.BoomboxController",
				compatibility.critical
			}
		};

		private List<PluginInfo> loadedPlugins = new List<PluginInfo>();

		public static readonly int[] CompatibleGameVersions = new int[1] { 45 };

		public static bool sessionWaiting = true;

		public static bool hostDataWaiting = true;

		public static bool ishost = false;

		public static bool alreadypatched = false;

		public static bool weathersReadyToShare = false;

		public static bool isInGame = false;

		public static int delayedLevelChange = -1;

		public static string lastKickReason = string.Empty;

		private static readonly Harmony Harmony = new Harmony("LethalExpansion");

		public static ManualLogSource Log = new ManualLogSource("LethalExpansion");

		public static ConfigFile config;

		public static NetworkManager networkManager;

		public GameObject SpaceLight;

		public GameObject terrainfixer;

		public static Transform currentWaterSurface;

		private int width = 256;

		private int height = 256;

		private int depth = 20;

		private float scale = 20f;

		private void Awake()
		{
			//IL_0bec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf2: Expected O, but got Unknown
			//IL_0c3b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c48: Expected O, but got Unknown
			//IL_0c4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c5a: Expected O, but got Unknown
			//IL_0cc1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cce: Expected O, but got Unknown
			//IL_0cd5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce2: Expected O, but got Unknown
			//IL_0d00: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d05: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d11: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: LethalExpansion, VersionString: 1.3.11 is loading...");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Getting other plugins list");
			loadedPlugins = GetLoadedPlugins();
			foreach (PluginInfo loadedPlugin in loadedPlugins)
			{
				if (!(loadedPlugin.Metadata.GUID != "LethalExpansion"))
				{
					continue;
				}
				if (CompatibleMods.ContainsKey(loadedPlugin.Metadata.GUID))
				{
					switch (CompatibleMods[loadedPlugin.Metadata.GUID])
					{
					case compatibility.unknown:
						Console.BackgroundColor = ConsoleColor.Gray;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					case compatibility.perfect:
						Console.BackgroundColor = ConsoleColor.Blue;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					case compatibility.good:
						Console.BackgroundColor = ConsoleColor.Green;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					case compatibility.medium:
						Console.BackgroundColor = ConsoleColor.Yellow;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogWarning((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					case compatibility.bad:
						Console.BackgroundColor = ConsoleColor.Red;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogError((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					case compatibility.critical:
						Console.BackgroundColor = ConsoleColor.Magenta;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogFatal((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					default:
						Console.BackgroundColor = ConsoleColor.Gray;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
						Console.ResetColor();
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {CompatibleMods[loadedPlugin.Metadata.GUID]}");
						break;
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)"------------------------------");
				}
				else
				{
					Console.BackgroundColor = ConsoleColor.Gray;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"                              ");
					Console.ResetColor();
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Plugin: {loadedPlugin.Metadata.Name} - Version: {loadedPlugin.Metadata.Version} - Compatibility: {compatibility.unknown}");
					((BaseUnityPlugin)this).Logger.LogInfo((object)"------------------------------");
				}
			}
			config = ((BaseUnityPlugin)this).Config;
			ConfigManager.Instance.AddItem(new ConfigItem("GlobalTimeSpeedMultiplier", 1.4f, "Time", "Change the global time speed", 0.1f, 3f));
			ConfigManager.Instance.AddItem(new ConfigItem("NumberOfHours", 18, "Time", "Max lenght of an Expedition in hours. (Begin at 6 AM | 18 = Midnight)", 6, 20));
			ConfigManager.Instance.AddItem(new ConfigItem("DeadlineDaysAmount", 3, "Expeditions", "Change amount of days for the Quota.", 1, 9));
			ConfigManager.Instance.AddItem(new ConfigItem("StartingCredits", 60, "Expeditions", "Change amount of starting Credit.", 0, 1000));
			ConfigManager.Instance.AddItem(new ConfigItem("MoonsRoutePricesMultiplier", 1f, "Moons", "Change the Cost of the Moon Routes.", 0f, 5f));
			ConfigManager.Instance.AddItem(new ConfigItem("StartingQuota", 130, "Expeditions", "Change the starting Quota.", 0, 1000, sync: true, optional: true));
			ConfigManager.Instance.AddItem(new ConfigItem("ScrapAmountMultiplier", 1f, "Dungeons", "Change the amount of Scraps in dungeons.", 0f, 10f));
			ConfigManager.Instance.AddItem(new ConfigItem("ScrapValueMultiplier", 0.4f, "Dungeons", "Change the value of Scraps.", 0f, 10f));
			ConfigManager.Instance.AddItem(new ConfigItem("MapSizeMultiplier", 1.5f, "Dungeons", "Change the size of the Dungeons. (Can crash when under 1.0)", 0.8f, 10f));
			ConfigManager.Instance.AddItem(new ConfigItem("PreventMineToExplodeWithItems", false, "Dungeons", "Prevent Landmines to explode by dropping items on them"));
			ConfigManager.Instance.AddItem(new ConfigItem("MineActivationWeight", 0.15f, "Dungeons", "Set the minimal weight to prevent Landmine's explosion (0.15 = 16 lb, Player = 2.0)", 0.01f, 5f));
			ConfigManager.Instance.AddItem(new ConfigItem("WeightUnit", 0, "HUD", "Change the carried Weight unit : 0 = Pounds (lb), 1 = Kilograms (kg) and 2 = Both", 0, 2, sync: false));
			ConfigManager.Instance.AddItem(new ConfigItem("ConvertPoundsToKilograms", true, "HUD", "Convert Pounds into Kilograms (16 lb = 7 kg) (Only effective if WeightUnit = 1)", null, null, sync: false));
			ConfigManager.Instance.AddItem(new ConfigItem("PreventScrapWipeWhenAllPlayersDie", false, "Expeditions", "Prevent the Scraps Wipe when all players die."));
			ConfigManager.Instance.AddItem(new ConfigItem("24HoursClock", false, "HUD", "Display a 24h clock instead of 12h.", null, null, sync: false));
			ConfigManager.Instance.AddItem(new ConfigItem("ClockAlwaysVisible", false, "HUD", "Display clock while inside of the Ship."));
			ConfigManager.Instance.AddItem(new ConfigItem("AutomaticDeadline", false, "Expeditions", "Automatically increase the Deadline depending of the required quota."));
			ConfigManager.Instance.AddItem(new ConfigItem("AutomaticDeadlineStage", 300, "Expeditions", "Increase the quota deadline of one day each time the quota exceeds this value.", 100, 3000));
			ConfigManager.Instance.AddItem(new ConfigItem("LoadModules", true, "Modules", "Load SDK Modules that add new content to the game. Disable it to play with Vanilla players. (RESTART REQUIRED)", null, null, sync: false, optional: false, hidden: false, requireRestart: true));
			ConfigManager.Instance.AddItem(new ConfigItem("MaxItemsInShip", 45, "Expeditions", "Change the Items cap can be kept in the ship.", 10, 500));
			ConfigManager.Instance.AddItem(new ConfigItem("ShowMoonWeatherInCatalogue", true, "HUD", "Display the current weather of Moons in the Terminal's Moon Catalogue."));
			ConfigManager.Instance.AddItem(new ConfigItem("ShowMoonRankInCatalogue", false, "HUD", "Display the rank of Moons in the Terminal's Moon Catalogue."));
			ConfigManager.Instance.AddItem(new ConfigItem("ShowMoonPriceInCatalogue", false, "HUD", "Display the route price of Moons in the Terminal's Moon Catalogue."));
			ConfigManager.Instance.AddItem(new ConfigItem("QuotaIncreaseSteepness", 16, "Expeditions", "Change the Quota Increase Steepness. (Highter = less steep exponential increase)", 0, 32));
			ConfigManager.Instance.AddItem(new ConfigItem("QuotaBaseIncrease", 100, "Expeditions", "Change the Quota Base Increase.", 0, 300));
			ConfigManager.Instance.AddItem(new ConfigItem("KickPlayerWithoutMod", false, "Lobby", "Kick the players without Lethal Expansion installer. (Will be kicked anyway if LoadModules is True)"));
			ConfigManager.Instance.AddItem(new ConfigItem("BrutalCompanyPlusCompatibility", false, "Compatibility", "Leave Brutal Company Plus control the Quota settings."));
			ConfigManager.Instance.AddItem(new ConfigItem("LethalAdjustmentsCompatibility", false, "Compatibility", "Leave Lethal Adjustments control the Dungeon settings."));
			ConfigManager.Instance.AddItem(new ConfigItem("CoomfyDungeonCompatibility", false, "Compatibility", "Let Coomfy Dungeons control the Dungeon size & scrap settings."));
			ConfigManager.Instance.AddItem(new ConfigItem("SettingsDebug", false, "Debug", "Show an output of every settings in the Console. (The Console must listen Info messages)", null, null, sync: false));
			ConfigManager.Instance.ReadConfig();
			((BaseUnityPlugin)this).Config.SettingChanged += ConfigSettingChanged;
			AssetBundlesManager.Instance.LoadAllAssetBundles();
			SceneManager.sceneLoaded += OnSceneLoaded;
			SceneManager.sceneUnloaded += OnSceneUnloaded;
			Harmony.PatchAll(typeof(GameNetworkManager_Patch));
			Harmony.PatchAll(typeof(Terminal_Patch));
			Harmony.PatchAll(typeof(MenuManager_Patch));
			Harmony.PatchAll(typeof(GrabbableObject_Patch));
			Harmony.PatchAll(typeof(RoundManager_Patch));
			Harmony.PatchAll(typeof(TimeOfDay_Patch));
			Harmony.PatchAll(typeof(HUDManager_Patch));
			Harmony.PatchAll(typeof(StartOfRound_Patch));
			Harmony.PatchAll(typeof(EntranceTeleport_Patch));
			Harmony.PatchAll(typeof(Landmine_Patch));
			Harmony.PatchAll(typeof(AudioReverbTrigger_Patch));
			Harmony.PatchAll(typeof(InteractTrigger_Patch));
			Harmony.PatchAll(typeof(RuntimeDungeon));
			Harmony val = new Harmony("LethalExpansion");
			MethodInfo methodInfo = AccessTools.Method(typeof(BaboonBirdAI), "GrabScrap", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(HoarderBugAI), "GrabItem", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(MonsterGrabItem_Patch), "MonsterGrabItem", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(HoarderBugAI), "DropItem", (Type[])null, (Type[])null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(MonsterGrabItem_Patch), "MonsterDropItem_Patch", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(HoarderBugAI), "KillEnemy", (Type[])null, (Type[])null);
			MethodInfo methodInfo7 = AccessTools.Method(typeof(MonsterGrabItem_Patch), "KillEnemy_Patch", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(methodInfo7), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			HDRenderPipelineAsset val2 = (HDRenderPipelineAsset)(object)((currentRenderPipeline is HDRenderPipelineAsset) ? currentRenderPipeline : null);
			if ((Object)(object)val2 != (Object)null)
			{
				RenderPipelineSettings currentPlatformRenderPipelineSettings = val2.currentPlatformRenderPipelineSettings;
				currentPlatformRenderPipelineSettings.supportWater = true;
				val2.currentPlatformRenderPipelineSettings = currentPlatformRenderPipelineSettings;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Water support applied to the HDRenderPipelineAsset.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"HDRenderPipelineAsset not found.");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: LethalExpansion, VersionString: 1.3.11 is loaded.");
		}

		private List<PluginInfo> GetLoadedPlugins()
		{
			return Chainloader.PluginInfos.Values.ToList();
		}

		private float[,] GenerateHeights()
		{
			float[,] array = new float[width, height];
			for (int i = 0; i < width; i++)
			{
				for (int j = 0; j < height; j++)
				{
					array[i, j] = CalculateHeight(i, j);
				}
			}
			return array;
		}

		private float CalculateHeight(int x, int y)
		{
			float num = (float)x / (float)width * scale;
			float num2 = (float)y / (float)height * scale;
			return Mathf.PerlinNoise(num, num2);
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Expected O, but got Unknown
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Expected O, but got Unknown
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_075b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Loading scene: " + ((Scene)(ref scene)).name));
			if (((Scene)(ref scene)).name == "InitScene")
			{
				networkManager = GameObject.Find("NetworkManager").GetComponent<NetworkManager>();
			}
			if (((Scene)(ref scene)).name == "MainMenu")
			{
				sessionWaiting = true;
				hostDataWaiting = true;
				ishost = false;
				alreadypatched = false;
				delayedLevelChange = -1;
				isInGame = false;
				AssetGather.Instance.AddAudioMixer(GameObject.Find("Canvas/MenuManager").GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer);
				SettingsMenu.Instance.InitSettingsMenu();
				if (lastKickReason != null && lastKickReason.Length > 0)
				{
					PopupManager.Instance.InstantiatePopup(scene, "Kicked from Lobby", "You have been kicked\r\nReason: " + lastKickReason, "Ok", "Ignore");
				}
				if (!ConfigManager.Instance.FindEntryValue<bool>("CoomfyDungeonCompatibility") && loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "CoomfyDungeon"))
				{
					PopupManager instance = PopupManager.Instance;
					Scene sceneFocus = scene;
					object obj = <>c.<>9__32_0;
					if (obj == null)
					{
						UnityAction val = delegate
						{
							ConfigManager.Instance.SetItemValue("CoomfyDungeonCompatibility", value: true);
							ConfigManager.Instance.SetEntryValue("CoomfyDungeonCompatibility", value: true);
						};
						<>c.<>9__32_0 = val;
						obj = (object)val;
					}
					instance.InstantiatePopup(sceneFocus, "CoomfyDungeon mod found", "Warning: CoomfyDungeon is incompatible with LethalExpansion, Would you like to enable the compatibility mode? Otherwise dungeon generation Desync may occurs!", "Yes", "No", (UnityAction)obj, null, 20, 18);
				}
				if (loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "BiggerLobby"))
				{
					PopupManager.Instance.InstantiatePopup(scene, "BiggerLobby mod found", "Warning: BiggerLobby is incompatible with LethalExpansion, host/client synchronization will break and dungeon generation Desync may occurs!", "Ok", "Ignore", null, null, 20, 18);
				}
				if (loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "KoderTech.BoomboxController"))
				{
					PopupManager.Instance.InstantiatePopup(scene, "BoomboxController mod found", "Warning: BoomboxController is incompatible with LethalExpansion, host/client synchronization will break and dungeon generation Desync may occurs!", "Ok", "Ignore", null, null, 20, 18);
				}
			}
			if (((Scene)(ref scene)).name == "CompanyBuilding")
			{
				SpaceLight.SetActive(false);
				terrainfixer.SetActive(false);
			}
			if (((Scene)(ref scene)).name == "SampleSceneRelay")
			{
				SpaceLight = Object.Instantiate<GameObject>(AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Prefabs/SpaceLight.prefab"));
				SceneManager.MoveGameObjectToScene(SpaceLight, scene);
				Mesh mesh = AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Meshes/MonitorWall.fbx").GetComponent<MeshFilter>().mesh;
				GameObject val2 = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube");
				val2.GetComponent<MeshFilter>().mesh = mesh;
				MeshRenderer component = val2.GetComponent<MeshRenderer>();
				GameObject val3 = Object.Instantiate<GameObject>(GameObject.Find("Systems/GameSystems/TimeAndWeather/Flooding"));
				Object.Destroy((Object)(object)val3.GetComponent<FloodWeather>());
				((Object)val3).name = "WaterSurface";
				val3.transform.position = Vector3.zero;
				((Component)val3.transform.Find("Water")).GetComponent<MeshFilter>().sharedMesh = null;
				SpawnPrefab.Instance.waterSurface = val3;
				((Renderer)component).materials = (Material[])(object)new Material[9]
				{
					((Renderer)component).materials[0],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[1],
					((Renderer)component).materials[2]
				};
				((Component)StartOfRound.Instance.screenLevelDescription).gameObject.AddComponent<AutoScrollText>();
				AssetGather.Instance.AddAudioMixer(GameObject.Find("Systems/Audios/DiageticBackground").GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer);
				terrainfixer = new GameObject();
				((Object)terrainfixer).name = "terrainfixer";
				terrainfixer.transform.position = new Vector3(0f, -500f, 0f);
				Terrain val4 = terrainfixer.AddComponent<Terrain>();
				TerrainData val5 = new TerrainData();
				val5.heightmapResolution = width + 1;
				val5.size = new Vector3((float)width, (float)depth, (float)height);
				val5.SetHeights(0, 0, GenerateHeights());
				val4.terrainData = val5;
				Terminal_Patch.ResetFireExitAmounts();
				Object[] array = Resources.FindObjectsOfTypeAll(typeof(Volume));
				for (int i = 0; i < array.Length; i++)
				{
					Object obj2 = array[i];
					if ((Object)(object)((Volume)((obj2 is Volume) ? obj2 : null)).sharedProfile == (Object)null)
					{
						Object obj3 = array[i];
						((Volume)((obj3 is Volume) ? obj3 : null)).sharedProfile = AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<VolumeProfile>("Assets/Mods/LethalExpansion/Sky and Fog Global Volume Profile.asset");
					}
				}
				waitForSession().GetAwaiter();
				isInGame = true;
			}
			if (((Scene)(ref scene)).name.StartsWith("Level"))
			{
				SpaceLight.SetActive(false);
				terrainfixer.SetActive(false);
				if (ConfigManager.Instance.FindItemValue<bool>("SettingsDebug"))
				{
					foreach (ConfigItem item in ConfigManager.Instance.GetAll())
					{
						Log.LogInfo((object)"==========");
						Log.LogInfo((object)item.Key);
						Log.LogInfo(item.Value);
						Log.LogInfo(item.DefaultValue);
						Log.LogInfo((object)item.Sync);
					}
				}
			}
			if (!(((Scene)(ref scene)).name == "InitSceneLaunchOptions") || !isInGame)
			{
				return;
			}
			SpaceLight.SetActive(false);
			terrainfixer.SetActive(false);
			GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
			foreach (GameObject val6 in rootGameObjects)
			{
				val6.SetActive(false);
			}
			if (ConfigManager.Instance.FindItemValue<bool>("SettingsDebug"))
			{
				foreach (ConfigItem item2 in ConfigManager.Instance.GetAll())
				{
					Log.LogInfo((object)"==========");
					Log.LogInfo((object)item2.Key);
					Log.LogInfo(item2.Value);
					Log.LogInfo(item2.DefaultValue);
					Log.LogInfo((object)item2.Sync);
				}
			}
			LoadCustomMoon(scene).GetAwaiter();
		}

		private async Task LoadCustomMoon(Scene scene)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			await Task.Delay(400);
			try
			{
				if ((Object)(object)Terminal_Patch.newMoons[StartOfRound.Instance.currentLevelID].MainPrefab != (Object)null && (Object)(object)Terminal_Patch.newMoons[StartOfRound.Instance.currentLevelID].MainPrefab.transform != (Object)null)
				{
					CheckAndRemoveIllegalComponents(Terminal_Patch.newMoons[StartOfRound.Instance.currentLevelID].MainPrefab.transform);
					GameObject mainPrefab = Object.Instantiate<GameObject>(Terminal_Patch.newMoons[StartOfRound.Instance.currentLevelID].MainPrefab);
					currentWaterSurface = mainPrefab.transform.Find("Environment/Water");
					if ((Object)(object)mainPrefab != (Object)null)
					{
						SceneManager.MoveGameObjectToScene(mainPrefab, scene);
						Transform DiageticBackground = mainPrefab.transform.Find("Systems/Audio/DiageticBackground");
						if ((Object)(object)DiageticBackground != (Object)null)
						{
							((Component)DiageticBackground).GetComponent<AudioSource>().outputAudioMixerGroup = (AssetGather.Instance.audioMixers.ContainsKey("Diagetic") ? AssetGather.Instance.audioMixers["Diagetic"].Item2.First((AudioMixerGroup a) => ((Object)a).name == "Master") : null);
						}
						Terrain[] Terrains = mainPrefab.GetComponentsInChildren<Terrain>();
						if (Terrains != null && Terrains.Length != 0)
						{
							Terrain[] array = Terrains;
							foreach (Terrain terrain in array)
							{
								terrain.drawInstanced = true;
							}
						}
					}
				}
				string[] _tmp = new string[5] { "MapPropsContainer", "OutsideAINode", "SpawnDenialPoint", "ItemShipLandingNode", "OutsideLevelNavMesh" };
				string[] array2 = _tmp;
				foreach (string s in array2)
				{
					if ((Object)(object)GameObject.FindGameObjectWithTag(s) == (Object)null || GameObject.FindGameObjectsWithTag(s).Any(delegate(GameObject o)
					{
						//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)
						Scene scene2 = o.scene;
						return ((Scene)(ref scene2)).name != "InitSceneLaunchOptions";
					}))
					{
						GameObject obj = new GameObject();
						((Object)obj).name = s;
						obj.tag = s;
						obj.transform.position = new Vector3(0f, -200f, 0f);
						SceneManager.MoveGameObjectToScene(obj, scene);
					}
				}
				await Task.Delay(200);
				GameObject DropShip = GameObject.Find("ItemShipAnimContainer");
				if ((Object)(object)DropShip != (Object)null)
				{
					Transform ItemShip = DropShip.transform.Find("ItemShip");
					if ((Object)(object)ItemShip != (Object)null)
					{
						((Component)ItemShip).GetComponent<AudioSource>().outputAudioMixerGroup = (AssetGather.Instance.audioMixers.ContainsKey("Diagetic") ? AssetGather.Instance.audioMixers["Diagetic"].Item2.First((AudioMixerGroup a) => ((Object)a).name == "Master") : null);
					}
					Transform ItemShipMusicClose = DropShip.transform.Find("ItemShip/Music");
					if ((Object)(object)ItemShipMusicClose != (Object)null)
					{
						((Component)ItemShipMusicClose).GetComponent<AudioSource>().outputAudioMixerGroup = (AssetGather.Instance.audioMixers.ContainsKey("Diagetic") ? AssetGather.Instance.audioMixers["Diagetic"].Item2.First((AudioMixerGroup a) => ((Object)a).name == "Master") : null);
					}
					Transform ItemShipMusicFar = DropShip.transform.Find("ItemShip/Music/Music (1)");
					if ((Object)(object)ItemShipMusicFar != (Object)null)
					{
						((Component)ItemShipMusicFar).GetComponent<AudioSource>().outputAudioMixerGroup = (AssetGather.Instance.audioMixers.ContainsKey("Diagetic") ? AssetGather.Instance.audioMixers["Diagetic"].Item2.First((AudioMixerGroup a) => ((Object)a).name == "Master") : null);
					}
				}
				await Task.Delay(200);
				RuntimeDungeon runtimeDungeon2 = Object.FindObjectOfType<RuntimeDungeon>(false);
				if ((Object)(object)runtimeDungeon2 == (Object)null)
				{
					GameObject dungeonGenerator = new GameObject();
					((Object)dungeonGenerator).name = "DungeonGenerator";
					dungeonGenerator.tag = "DungeonGenerator";
					dungeonGenerator.transform.position = new Vector3(0f, -200f, 0f);
					runtimeDungeon2 = dungeonGenerator.AddComponent<RuntimeDungeon>();
					runtimeDungeon2.Generator.DungeonFlow = RoundManager.Instance.dungeonFlowTypes[0];
					runtimeDungeon2.Generator.LengthMultiplier = 0.8f;
					runtimeDungeon2.Generator.PauseBetweenRooms = 0.2f;
					runtimeDungeon2.GenerateOnStart = false;
					runtimeDungeon2.Root = dungeonGenerator;
					runtimeDungeon2.Generator.DungeonFlow = RoundManager.Instance.dungeonFlowTypes[0];
					UnityNavMeshAdapter dungeonNavMesh = dungeonGenerator.AddComponent<UnityNavMeshAdapter>();
					dungeonNavMesh.BakeMode = (RuntimeNavMeshBakeMode)3;
					dungeonNavMesh.LayerMask = LayerMask.op_Implicit(35072);
					SceneManager.MoveGameObjectToScene(dungeonGenerator, scene);
				}
				else if ((Object)(object)runtimeDungeon2.Generator.DungeonFlow == (Object)null)
				{
					runtimeDungeon2.Generator.DungeonFlow = RoundManager.Instance.dungeonFlowTypes[0];
				}
				GameObject OutOfBounds = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)OutOfBounds).name = "OutOfBounds";
				OutOfBounds.layer = 13;
				OutOfBounds.transform.position = new Vector3(0f, -300f, 0f);
				OutOfBounds.transform.localScale = new Vector3(1000f, 5f, 1000f);
				BoxCollider boxCollider = OutOfBounds.GetComponent<BoxCollider>();
				((Collider)boxCollider).isTrigger = true;
				OutOfBounds.AddComponent<OutOfBoundsTrigger>();
				Rigidbody rigidbody = OutOfBounds.AddComponent<Rigidbody>();
				rigidbody.useGravity = false;
				rigidbody.isKinematic = true;
				rigidbody.collisionDetectionMode = (CollisionDetectionMode)1;
				SceneManager.MoveGameObjectToScene(OutOfBounds, scene);
				await Task.Delay(200);
			}
			catch (Exception ex2)
			{
				Exception ex = ex2;
				Log.LogError((object)ex);
			}
		}

		private void CheckAndRemoveIllegalComponents(Transform root)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			try
			{
				Component[] components = ((Component)root).GetComponents<Component>();
				Component[] array = components;
				foreach (Component component in array)
				{
					if (!ComponentWhitelists.moonPrefabWhitelist.Any((Type whitelistType) => ((object)component).GetType() == whitelistType))
					{
						Log.LogWarning((object)("Removed illegal " + ((object)component).GetType().Name + " component."));
						Object.Destroy((Object)(object)component);
					}
				}
				foreach (Transform item in root)
				{
					Transform root2 = item;
					CheckAndRemoveIllegalComponents(root2);
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex.Message);
			}
		}

		private void OnSceneUnloaded(Scene scene)
		{
			if (((Scene)(ref scene)).name.Length > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Unloading scene: " + ((Scene)(ref scene)).name));
			}
			if (((Scene)(ref scene)).name.StartsWith("Level") || ((Scene)(ref scene)).name == "CompanyBuilding" || (((Scene)(ref scene)).name == "InitSceneLaunchOptions" && isInGame))
			{
				if ((Object)(object)SpaceLight != (Object)null)
				{
					SpaceLight.SetActive(true);
				}
				if ((Object)(object)currentWaterSurface != (Object)null)
				{
					currentWaterSurface = null;
				}
				Terminal_Patch.ResetFireExitAmounts();
			}
		}

		private async Task waitForSession()
		{
			while (sessionWaiting)
			{
				await Task.Delay(1000);
			}
			if (!ishost)
			{
				while (!sessionWaiting && hostDataWaiting)
				{
					NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.request, "hostconfig", string.Empty, 0L);
					await Task.Delay(3000);
				}
			}
			else
			{
				for (int i = 0; i < ConfigManager.Instance.GetAll().Count; i++)
				{
					if (ConfigManager.Instance.MustBeSync(i))
					{
						ConfigManager.Instance.SetItemValue(i, ConfigManager.Instance.FindEntryValue(i));
					}
				}
			}
			TimeOfDay.Instance.globalTimeSpeedMultiplier = ConfigManager.Instance.FindItemValue<float>("GlobalTimeSpeedMultiplier");
			TimeOfDay.Instance.numberOfHours = ConfigManager.Instance.FindItemValue<int>("NumberOfHours");
			if (!ConfigManager.Instance.FindItemValue<bool>("BrutalCompanyPlusCompatibility") || !loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "BrutalCompanyPlus"))
			{
				TimeOfDay.Instance.quotaVariables.deadlineDaysAmount = ConfigManager.Instance.FindItemValue<int>("DeadlineDaysAmount");
				TimeOfDay.Instance.quotaVariables.startingQuota = ConfigManager.Instance.FindItemValue<int>("StartingQuota");
				TimeOfDay.Instance.quotaVariables.startingCredits = ConfigManager.Instance.FindItemValue<int>("StartingCredits");
				TimeOfDay.Instance.quotaVariables.baseIncrease = ConfigManager.Instance.FindItemValue<int>("QuotaBaseIncrease");
				TimeOfDay.Instance.quotaVariables.increaseSteepness = ConfigManager.Instance.FindItemValue<int>("QuotaIncreaseSteepness");
			}
			bool hasLethalAdjustmentCompat = ConfigManager.Instance.FindItemValue<bool>("LethalAdjustmentsCompatibility") && loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "LethalAdjustments");
			bool ignoreScrapAmountAndMapSize = hasLethalAdjustmentCompat || (ConfigManager.Instance.FindItemValue<bool>("CoomfyDungeonCompatibility") && loadedPlugins.Any((PluginInfo p) => p.Metadata.GUID == "CoomfyDungeon"));
			if (!hasLethalAdjustmentCompat)
			{
				RoundManager.Instance.scrapValueMultiplier = ConfigManager.Instance.FindItemValue<float>("ScrapValueMultiplier");
			}
			if (!ignoreScrapAmountAndMapSize)
			{
				RoundManager.Instance.scrapAmountMultiplier = ConfigManager.Instance.FindItemValue<float>("ScrapAmountMultiplier");
				RoundManager.Instance.mapSizeMultiplier = ConfigManager.Instance.FindItemValue<float>("MapSizeMultiplier");
			}
			StartOfRound.Instance.maxShipItemCapacity = ConfigManager.Instance.FindItemValue<int>("MaxItemsInShip");
			if (!alreadypatched)
			{
				Terminal_Patch.MainPatch(GameObject.Find("TerminalScript").GetComponent<Terminal>());
				alreadypatched = true;
			}
		}

		private void ConfigSettingChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (val != null)
			{
				Log.LogInfo((object)$"{val.ChangedSetting.Definition.Key} Changed to {val.ChangedSetting.BoxedValue}");
			}
		}
	}
}
namespace LethalExpansion.Utils
{
	public class AssetBundlesManager
	{
		private static AssetBundlesManager _instance;

		public AssetBundle mainAssetBundle = AssetBundle.LoadFromFile(Assembly.GetExecutingAssembly().Location.Replace("LethalExpansion.dll", "lethalexpansion.lem"));

		public Dictionary<string, (AssetBundle, ModManifest)> assetBundles = new Dictionary<string, (AssetBundle, ModManifest)>();

		public readonly string[] forcedNative = new string[2] { "templatemod", "oldseaport" };

		public DirectoryInfo modPath = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);

		public DirectoryInfo modDirectory;

		public DirectoryInfo pluginsDirectory;

		public static AssetBundlesManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new AssetBundlesManager();
				}
				return _instance;
			}
		}

		public (AssetBundle, ModManifest) Load(string name)
		{
			return assetBundles[name.ToLower()];
		}

		public void LoadAllAssetBundles()
		{
			modDirectory = modPath.Parent;
			pluginsDirectory = modDirectory;
			while (pluginsDirectory != null && pluginsDirectory.Name != "plugins")
			{
				pluginsDirectory = pluginsDirectory.Parent;
			}
			if (pluginsDirectory != null)
			{
				LethalExpansion.Log.LogInfo((object)("Plugins folder found: " + pluginsDirectory.FullName));
				LethalExpansion.Log.LogInfo((object)("Mod path is: " + modDirectory.FullName));
				if (modDirectory.FullName == pluginsDirectory.FullName)
				{
					LethalExpansion.Log.LogWarning((object)("LethalExpansion is Rooting the Plugins folder, this is not recommended. " + modDirectory.FullName));
				}
				string[] files = Directory.GetFiles(pluginsDirectory.FullName, "*.lem", SearchOption.AllDirectories);
				foreach (string file in files)
				{
					LoadBundle(file);
				}
			}
			else
			{
				LethalExpansion.Log.LogWarning((object)"Mod is not in a plugins folder.");
			}
		}

		public void LoadBundle(string file)
		{
			if (forcedNative.Contains<string>(Path.GetFileNameWithoutExtension(file)) && !file.Contains(modDirectory.FullName))
			{
				LethalExpansion.Log.LogWarning((object)("Illegal use of reserved Asset Bundle name: " + Path.GetFileNameWithoutExtension(file) + " at: " + file + "."));
			}
			else
			{
				if (!(Path.GetFileName(file) != "lethalexpansion.lem"))
				{
					return;
				}
				if (!assetBundles.ContainsKey(Path.GetFileNameWithoutExtension(file)))
				{
					Stopwatch stopwatch = new Stopwatch();
					AssetBundle val = null;
					try
					{
						stopwatch.Start();
						val = AssetBundle.LoadFromFile(file);
						stopwatch.Stop();
					}
					catch (Exception ex)
					{
						LethalExpansion.Log.LogError((object)ex);
					}
					if ((Object)(object)val != (Object)null)
					{
						string text = "Assets/Mods/" + Path.GetFileNameWithoutExtension(file) + "/ModManifest.asset";
						ModManifest modManifest = val.LoadAsset<ModManifest>(text);
						if ((Object)(object)modManifest != (Object)null)
						{
							if (!assetBundles.Any((KeyValuePair<string, (AssetBundle, ModManifest)> b) => b.Value.Item2.modName == modManifest.modName))
							{
								LethalExpansion.Log.LogInfo((object)string.Format("Module found: {0} v{1} Loaded in {2}ms", modManifest.modName, (modManifest.GetVersion() != null) ? ((object)modManifest.GetVersion()).ToString() : "0.0.0.0", stopwatch.ElapsedMilliseconds));
								if (modManifest.GetVersion() == null || ((object)modManifest.GetVersion()).ToString() == "0.0.0.0")
								{
									LethalExpansion.Log.LogWarning((object)("Module " + modManifest.modName + " have no version number, this is unsafe!"));
								}
								assetBundles.Add(Path.GetFileNameWithoutExtension(file).ToLower(), (val, modManifest));
							}
							else
							{
								LethalExpansion.Log.LogWarning((object)("Another mod with same name is already loaded: " + modManifest.modName));
								val.Unload(true);
								LethalExpansion.Log.LogInfo((object)("AssetBundle unloaded: " + Path.GetFileName(file)));
							}
						}
						else
						{
							LethalExpansion.Log.LogWarning((object)("AssetBundle have no ModManifest: " + Path.GetFileName(file)));
							val.Unload(true);
							LethalExpansion.Log.LogInfo((object)("AssetBundle unloaded: " + Path.GetFileName(file)));
						}
					}
					else
					{
						LethalExpansion.Log.LogWarning((object)("File is not an AssetBundle: " + Path.GetFileName(file)));
					}
				}
				else
				{
					LethalExpansion.Log.LogWarning((object)("AssetBundle with same name already loaded: " + Path.GetFileName(file)));
				}
			}
		}

		public bool BundleLoaded(string bundleName)
		{
			return assetBundles.ContainsKey(bundleName.ToLower());
		}

		public bool BundlesLoaded(string[] bundleNames)
		{
			foreach (string text in bundleNames)
			{
				if (!assetBundles.ContainsKey(text.ToLower()))
				{
					return false;
				}
			}
			return true;
		}

		public bool IncompatibleBundlesLoaded(string[] bundleNames)
		{
			foreach (string text in bundleNames)
			{
				if (assetBundles.ContainsKey(text.ToLower()))
				{
					return true;
				}
			}
			return false;
		}
	}
	public class AssetGather
	{
		private static AssetGather _instance;

		public Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();

		public Dictionary<string, (AudioMixer, AudioMixerGroup[])> audioMixers = new Dictionary<string, (AudioMixer, AudioMixerGroup[])>();

		public Dictionary<string, GameObject> planetPrefabs = new Dictionary<string, GameObject>();

		public Dictionary<string, GameObject> mapObjects = new Dictionary<string, GameObject>();

		public Dictionary<string, SpawnableOutsideObject> outsideObjects = new Dictionary<string, SpawnableOutsideObject>();

		public Dictionary<string, Item> scraps = new Dictionary<string, Item>();

		public Dictionary<string, LevelAmbienceLibrary> levelAmbiances = new Dictionary<string, LevelAmbienceLibrary>();

		public Dictionary<string, EnemyType> enemies = new Dictionary<string, EnemyType>();

		public Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();

		public static AssetGather Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new AssetGather();
				}
				return _instance;
			}
		}

		public void GetList()
		{
			LethalExpansion.Log.LogInfo((object)"Audio Clips");
			foreach (KeyValuePair<string, AudioClip> audioClip in audioClips)
			{
				LethalExpansion.Log.LogInfo((object)audioClip.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Audio Mixers");
			foreach (KeyValuePair<string, (AudioMixer, AudioMixerGroup[])> audioMixer in audioMixers)
			{
				LethalExpansion.Log.LogInfo((object)audioMixer.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Planet Prefabs");
			foreach (KeyValuePair<string, GameObject> planetPrefab in planetPrefabs)
			{
				LethalExpansion.Log.LogInfo((object)planetPrefab.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Map Objects");
			foreach (KeyValuePair<string, GameObject> mapObject in mapObjects)
			{
				LethalExpansion.Log.LogInfo((object)mapObject.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Outside Objects");
			foreach (KeyValuePair<string, SpawnableOutsideObject> outsideObject in outsideObjects)
			{
				LethalExpansion.Log.LogInfo((object)outsideObject.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Scraps");
			foreach (KeyValuePair<string, Item> scrap in scraps)
			{
				LethalExpansion.Log.LogInfo((object)scrap.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Level Ambiances");
			foreach (KeyValuePair<string, LevelAmbienceLibrary> levelAmbiance in levelAmbiances)
			{
				LethalExpansion.Log.LogInfo((object)levelAmbiance.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Enemies");
			foreach (KeyValuePair<string, EnemyType> enemy in enemies)
			{
				LethalExpansion.Log.LogInfo((object)enemy.Key);
			}
			LethalExpansion.Log.LogInfo((object)"Sprites");
			foreach (KeyValuePair<string, Sprite> sprite in sprites)
			{
				LethalExpansion.Log.LogInfo((object)sprite.Key);
			}
		}

		public void AddAudioClip(AudioClip clip)
		{
			if ((Object)(object)clip != (Object)null && !audioClips.ContainsKey(((Object)clip).name) && !audioClips.ContainsValue(clip))
			{
				audioClips.Add(((Object)clip).name, clip);
			}
		}

		public void AddAudioClip(string name, AudioClip clip)
		{
			if ((Object)(object)clip != (Object)null && !audioClips.ContainsKey(name) && !audioClips.ContainsValue(clip))
			{
				audioClips.Add(name, clip);
			}
		}

		public void AddAudioMixer(AudioMixer mixer)
		{
			if (!((Object)(object)mixer != (Object)null) || audioMixers.ContainsKey(((Object)mixer).name))
			{
				return;
			}
			List<AudioMixerGroup> list = new List<AudioMixerGroup>();
			AudioMixerGroup[] array = mixer.FindMatchingGroups(string.Empty);
			foreach (AudioMixerGroup val in array)
			{
				if ((Object)(object)val != (Object)null && !list.Contains(val))
				{
					list.Add(val);
				}
			}
			audioMixers.Add(((Object)mixer).name, (mixer, list.ToArray()));
		}

		public void AddPlanetPrefabs(GameObject prefab)
		{
			if ((Object)(object)prefab != (Object)null && !planetPrefabs.ContainsKey(((Object)prefab).name) && !planetPrefabs.ContainsValue(prefab))
			{
				planetPrefabs.Add(((Object)prefab).name, prefab);
			}
		}

		public void AddPlanetPrefabs(string name, GameObject prefab)
		{
			if ((Object)(object)prefab != (Object)null && !planetPrefabs.ContainsKey(name) && !planetPrefabs.ContainsValue(prefab))
			{
				planetPrefabs.Add(name, prefab);
			}
		}

		public void AddMapObjects(GameObject mapObject)
		{
			if ((Object)(object)mapObject != (Object)null && !mapObjects.ContainsKey(((Object)mapObject).name) && !mapObjects.ContainsValue(mapObject))
			{
				mapObjects.Add(((Object)mapObject).name, mapObject);
			}
		}

		public void AddOutsideObject(SpawnableOutsideObject outsideObject)
		{
			if ((Object)(object)outsideObject != (Object)null && !outsideObjects.ContainsKey(((Object)outsideObject).name) && !outsideObjects.ContainsValue(outsideObject))
			{
				outsideObjects.Add(((Object)outsideObject).name, outsideObject);
			}
		}

		public void AddScrap(Item scrap)
		{
			if ((Object)(object)scrap != (Object)null && !scraps.ContainsKey(((Object)scrap).name) && !scraps.ContainsValue(scrap))
			{
				scraps.Add(((Object)scrap).name, scrap);
			}
		}

		public void AddLevelAmbiances(LevelAmbienceLibrary levelAmbiance)
		{
			if ((Object)(object)levelAmbiance != (Object)null && !levelAmbiances.ContainsKey(((Object)levelAmbiance).name) && !levelAmbiances.ContainsValue(levelAmbiance))
			{
				levelAmbiances.Add(((Object)levelAmbiance).name, levelAmbiance);
			}
		}

		public void AddEnemies(EnemyType enemie)
		{
			if ((Object)(object)enemie != (Object)null && !enemies.ContainsKey(((Object)enemie).name) && !enemies.ContainsValue(enemie))
			{
				enemies.Add(((Object)enemie).name, enemie);
			}
		}

		public void AddSprites(Sprite sprite)
		{
			if ((Object)(object)sprite != (Object)null && !sprites.ContainsKey(((Object)sprite).name) && !sprites.ContainsValue(sprite))
			{
				sprites.Add(((Object)sprite).name, sprite);
			}
		}

		public void AddSprites(string name, Sprite sprite)
		{
			if ((Object)(object)sprite != (Object)null && !sprites.ContainsKey(name) && !sprites.ContainsValue(sprite))
			{
				sprites.Add(name, sprite);
			}
		}
	}
	public class ChatMessageProcessor
	{
		public static bool ProcessMessage(string message)
		{
			if (Regex.IsMatch(message, "^\\[sync\\].*\\[sync\\]$"))
			{
				try
				{
					string value = Regex.Match(message, "^\\[sync\\](.*)\\[sync\\]$").Groups[1].Value;
					string[] array = value.Split(new char[1] { '|' });
					if (array.Length == 3)
					{
						NetworkPacketManager.packetType packetType = (NetworkPacketManager.packetType)int.Parse(array[0]);
						string[] array2 = array[1].Split(new char[1] { '>' });
						ulong num = ulong.Parse(array2[0]);
						long num2 = long.Parse(array2[1]);
						string[] array3 = array[2].Split(new char[1] { '=' });
						string header = array3[0];
						string packet = array3[1];
						if (num2 == -1 || num2 == (long)((NetworkBehaviour)RoundManager.Instance).NetworkManager.LocalClientId)
						{
							if (num != 0)
							{
								NetworkPacketManager.Instance.CancelTimeout((long)num);
							}
							LethalExpansion.Log.LogInfo((object)message);
							switch (packetType)
							{
							case NetworkPacketManager.packetType.request:
								ProcessRequest(num, header, packet);
								break;
							case NetworkPacketManager.packetType.data:
								ProcessData(num, header, packet);
								break;
							case NetworkPacketManager.packetType.other:
								LethalExpansion.Log.LogInfo((object)"Unsupported type.");
								break;
							default:
								LethalExpansion.Log.LogInfo((object)"Unrecognized type.");
								break;
							}
						}
					}
					return true;
				}
				catch (Exception ex)
				{
					LethalExpansion.Log.LogError((object)ex);
					return false;
				}
			}
			return false;
		}

		private static void ProcessRequest(ulong sender, string header, string packet)
		{
			try
			{
				switch (header)
				{
				case "clientinfo":
				{
					if (LethalExpansion.ishost || sender != 0)
					{
						break;
					}
					string text2 = LethalExpansion.ModVersion.ToString() + "-";
					foreach (KeyValuePair<string, (AssetBundle, ModManifest)> assetBundle in AssetBundlesManager.Instance.assetBundles)
					{
						text2 = text2 + assetBundle.Key + "v" + ((object)assetBundle.Value.Item2.GetVersion()).ToString() + "&";
					}
					text2 = text2.Remove(text2.Length - 1);
					NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.data, "clientinfo", text2, 0L);
					break;
				}
				case "hostconfig":
					if (LethalExpansion.ishost && sender != 0)
					{
						NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.request, "clientinfo", string.Empty, (long)sender);
					}
					break;
				case "hostweathers":
					if (LethalExpansion.ishost && sender != 0L && LethalExpansion.weathersReadyToShare)
					{
						string text = string.Empty;
						int[] currentWeathers = StartOfRound_Patch.currentWeathers;
						foreach (int num in currentWeathers)
						{
							text = text + num + "&";
						}
						text = text.Remove(text.Length - 1);
						NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.data, "hostweathers", text, (long)sender, waitForAnswer: false);
					}
					break;
				default:
					LethalExpansion.Log.LogInfo((object)"Unrecognized command.");
					break;
				}
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex);
			}
		}

		private static void ProcessData(ulong sender, string header, string packet)
		{
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				switch (header)
				{
				case "clientinfo":
				{
					if (!LethalExpansion.ishost || sender == 0)
					{
						break;
					}
					string[] array = ((!Enumerable.Contains(packet, '-')) ? new string[1] { packet } : packet.Split(new char[1] { '-' }));
					string text = string.Empty;
					foreach (KeyValuePair<string, (AssetBundle, ModManifest)> assetBundle in AssetBundlesManager.Instance.assetBundles)
					{
						text = text + assetBundle.Key + "v" + ((object)assetBundle.Value.Item2.GetVersion()).ToString() + "&";
					}
					if (text.Length > 0)
					{
						text = text.Remove(text.Length - 1);
					}
					if (array[0] != LethalExpansion.ModVersion.ToString())
					{
						if (StartOfRound.Instance.ClientPlayerList.ContainsKey(sender))
						{
							LethalExpansion.Log.LogError((object)$"Kicking {sender} for wrong version.");
							NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.data, "kickreason", "Wrong version.", (long)sender);
							StartOfRound.Instance.KickPlayer(StartOfRound.Instance.ClientPlayerList[sender]);
						}
						break;
					}
					if (array.Length > 1 && array[1] != text)
					{
						if (StartOfRound.Instance.ClientPlayerList.ContainsKey(sender))
						{
							LethalExpansion.Log.LogError((object)$"Kicking {sender} for wrong bundles.");
							NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.data, "kickreason", "Wrong bundles.", (long)sender);
							StartOfRound.Instance.KickPlayer(StartOfRound.Instance.ClientPlayerList[sender]);
						}
						break;
					}
					string text2 = string.Empty;
					foreach (ConfigItem item in ConfigManager.Instance.GetAll())
					{
						switch (item.type.Name)
						{
						case "Int32":
							text2 = text2 + "i" + ((int)item.Value).ToString(CultureInfo.InvariantCulture);
							break;
						case "Single":
							text2 = text2 + "f" + ((float)item.Value).ToString(CultureInfo.InvariantCulture);
							break;
						case "Boolean":
							text2 = text2 + "b" + (bool)item.Value;
							break;
						case "String":
							text2 = text2 + "s" + item;
							break;
						}
						text2 += "&";
					}
					text2 = text2.Remove(text2.Length - 1);
					NetworkPacketManager.Instance.sendPacket(NetworkPacketManager.packetType.data, "hostconfig", text2, (long)sender);
					break;
				}
				case "hostconfig":
				{
					if (LethalExpansion.ishost || sender != 0)
					{
						break;
					}
					string[] array2 = packet.Split(new char[1] { '&' });
					LethalExpansion.Log.LogInfo((object)("Received host config: " + packet));
					for (int i = 0; i < array2.Length; i++)
					{
						if (i < ConfigManager.Instance.GetCount() && ConfigManager.Instance.MustBeSync(i))
						{
							ConfigManager.Instance.SetItemValue(i, array2[i].Substring(1), array2[i][0]);
						}
					}
					LethalExpansion.hostDataWaiting = false;
					LethalExpansion.Log.LogInfo((object)"Updated config");
					break;
				}
				case "hostweathers":
				{
					if (LethalExpansion.ishost || sender != 0)
					{
						break;
					}
					string[] array3 = packet.Split(new char[1] { '&' });
					LethalExpansion.Log.LogInfo((object)("Received host weathers: " + packet));
					StartOfRound_Patch.currentWeathers = new int[array3.Length];
					for (int j = 0; j < array3.Length; j++)
					{
						int result = 0;
						if (int.TryParse(array3[j], out result))
						{
							StartOfRound_Patch.currentWeathers[j] = result;
							StartOfRound.Instance.levels[j].currentWeather = (LevelWeatherType)result;
						}
					}
					break;
				}
				case "kickreason":
					if (!LethalExpansion.ishost && sender == 0)
					{
						LethalExpansion.lastKickReason = packet;
					}
					break;
				default:
					LethalExpansion.Log.LogInfo((object)"Unrecognized property.");
					break;
				}
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex);
			}
		}
	}
	public class ComponentWhitelists
	{
		public static List<Type> moonPrefabWhitelist = new List<Type>
		{
			typeof(Transform),
			typeof(MeshFilter),
			typeof(MeshRenderer),
			typeof(SkinnedMeshRenderer),
			typeof(MeshCollider),
			typeof(BoxCollider),
			typeof(SphereCollider),
			typeof(CapsuleCollider),
			typeof(SphereCollider),
			typeof(TerrainCollider),
			typeof(WheelCollider),
			typeof(ArticulationBody),
			typeof(ConstantForce),
			typeof(ConfigurableJoint),
			typeof(FixedJoint),
			typeof(HingeJoint),
			typeof(Cloth),
			typeof(Rigidbody),
			typeof(NetworkObject),
			typeof(NetworkRigidbody),
			typeof(NetworkTransform),
			typeof(NetworkAnimator),
			typeof(Animator),
			typeof(Animation),
			typeof(Terrain),
			typeof(Tree),
			typeof(WindZone),
			typeof(DecalProjector),
			typeof(LODGroup),
			typeof(Light),
			typeof(HDAdditionalLightData),
			typeof(LightProbeGroup),
			typeof(LightProbeProxyVolume),
			typeof(LocalVolumetricFog),
			typeof(OcclusionArea),
			typeof(OcclusionPortal),
			typeof(ReflectionProbe),
			typeof(PlanarReflectionProbe),
			typeof(HDAdditionalReflectionData),
			typeof(Skybox),
			typeof(SortingGroup),
			typeof(SpriteRenderer),
			typeof(Volume),
			typeof(AudioSource),
			typeof(AudioReverbZone),
			typeof(AudioReverbFilter),
			typeof(AudioChorusFilter),
			typeof(AudioDistortionFilter),
			typeof(AudioEchoFilter),
			typeof(AudioHighPassFilter),
			typeof(AudioLowPassFilter),
			typeof(AudioListener),
			typeof(LensFlare),
			typeof(TrailRenderer),
			typeof(LineRenderer),
			typeof(ParticleSystem),
			typeof(ParticleSystemRenderer),
			typeof(ParticleSystemForceField),
			typeof(Projector),
			typeof(VideoPlayer),
			typeof(NavMeshSurface),
			typeof(NavMeshModifier),
			typeof(NavMeshModifierVolume),
			typeof(NavMeshLink),
			typeof(NavMeshObstacle),
			typeof(OffMeshLink),
			typeof(SI_AudioReverbPresets),
			typeof(SI_AudioReverbTrigger),
			typeof(SI_DungeonGenerator),
			typeof(SI_MatchLocalPlayerPosition),
			typeof(SI_AnimatedSun),
			typeof(SI_EntranceTeleport),
			typeof(SI_ScanNode),
			typeof(SI_DoorLock),
			typeof(SI_WaterSurface),
			typeof(SI_Ladder),
			typeof(SI_ItemDropship),
			typeof(SI_NetworkPrefabInstancier),
			typeof(SI_InteractTrigger),
			typeof(SI_DamagePlayer),
			typeof(SI_SoundYDistance),
			typeof(SI_AudioOutputInterface),
			typeof(PlayerShip)
		};

		public static List<Type> scrapWhitelist = new List<Type>
		{
			typeof(Transform),
			typeof(MeshFilter),
			typeof(MeshRenderer),
			typeof(SkinnedMeshRenderer),
			typeof(MeshCollider),
			typeof(BoxCollider),
			typeof(SphereCollider),
			typeof(CapsuleCollider),
			typeof(SphereCollider),
			typeof(TerrainCollider),
			typeof(WheelCollider),
			typeof(ArticulationBody),
			typeof(ConstantForce),
			typeof(ConfigurableJoint),
			typeof(FixedJoint),
			typeof(HingeJoint),
			typeof(Cloth),
			typeof(Rigidbody),
			typeof(NetworkObject),
			typeof(NetworkRigidbody),
			typeof(NetworkTransform),
			typeof(NetworkAnimator),
			typeof(Animator),
			typeof(Animation),
			typeof(DecalProjector),
			typeof(LODGroup),
			typeof(Light),
			typeof(HDAdditionalLightData),
			typeof(LightProbeGroup),
			typeof(LightProbeProxyVolume),
			typeof(LocalVolumetricFog),
			typeof(OcclusionArea),
			typeof(OcclusionPortal),
			typeof(ReflectionProbe),
			typeof(PlanarReflectionProbe),
			typeof(HDAdditionalReflectionData),
			typeof(SortingGroup),
			typeof(SpriteRenderer),
			typeof(AudioSource),
			typeof(AudioReverbZone),
			typeof(AudioReverbFilter),
			typeof(AudioChorusFilter),
			typeof(AudioDistortionFilter),
			typeof(AudioEchoFilter),
			typeof(AudioHighPassFilter),
			typeof(AudioLowPassFilter),
			typeof(AudioListener),
			typeof(LensFlare),
			typeof(TrailRenderer),
			typeof(LineRenderer),
			typeof(ParticleSystem),
			typeof(ParticleSystemRenderer),
			typeof(ParticleSystemForceField),
			typeof(VideoPlayer)
		};
	}
	public class ConfigManager
	{
		private static ConfigManager _instance;

		private List<ConfigItem> items = new List<ConfigItem>();

		private List<ConfigEntryBase> entries = new List<ConfigEntryBase>();

		public static ConfigManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new ConfigManager();
				}
				return _instance;
			}
		}

		public void AddItem(ConfigItem item)
		{
			try
			{
				items.Add(item);
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
			}
		}

		public void ReadConfig()
		{
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Expected O, but got Unknown
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Expected O, but got Unknown
			items = (from item in items
				orderby item.Tab, item.Key
				select item).ToList();
			try
			{
				for (int i = 0; i < items.Count; i++)
				{
					if (!items[i].Hidden)
					{
						string description = items[i].Description;
						description = description + "\nNetwork synchronization: " + (items[i].Sync ? "Yes" : "No");
						description = description + "\nMod required by clients: " + (items[i].Optional ? "No" : "Yes");
						switch (items[i].type.Name)
						{
						case "Int32":
							entries.Add((ConfigEntryBase)(object)LethalExpansion.config.Bind<int>(items[i].Tab, items[i].Key, (int)items[i].DefaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>((int)items[i].MinValue, (int)items[i].MaxValue), Array.Empty<object>())));
							break;
						case "Single":
							entries.Add((ConfigEntryBase)(object)LethalExpansion.config.Bind<float>(items[i].Tab, items[i].Key, (float)items[i].DefaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>((float)items[i].MinValue, (float)items[i].MaxValue), Array.Empty<object>())));
							break;
						case "Boolean":
							entries.Add((ConfigEntryBase)(object)LethalExpansion.config.Bind<bool>(items[i].Tab, items[i].Key, (bool)items[i].DefaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())));
							break;
						case "String":
							entries.Add((ConfigEntryBase)(object)LethalExpansion.config.Bind<string>(items[i].Tab, items[i].Key, (string)items[i].DefaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())));
							break;
						}
						if (!items[i].Sync)
						{
							items[i].Value = entries.Last().BoxedValue;
						}
					}
					else
					{
						entries.Add(null);
					}
				}
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
			}
		}

		public object FindItemValue(string key)
		{
			try
			{
				return items.First((ConfigItem item) => item.Key == key).Value;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public object FindItemValue(int index)
		{
			try
			{
				return items[index].Value;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public object FindEntryValue(string key)
		{
			try
			{
				return entries.First((ConfigEntryBase item) => item.Definition.Key == key).BoxedValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public object FindEntryValue(int index)
		{
			try
			{
				return entries[index].BoxedValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public bool RequireRestart(string key)
		{
			try
			{
				return items.First((ConfigItem item) => item.Key == key).RequireRestart;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public bool RequireRestart(int index)
		{
			try
			{
				return items[index].RequireRestart;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public string FindDescription(string key)
		{
			try
			{
				return items.First((ConfigItem item) => item.Key == key).Description;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public string FindDescription(int index)
		{
			try
			{
				return items[index].Description;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public (bool, bool) FindNetInfo(string key)
		{
			try
			{
				ConfigItem configItem = items.First((ConfigItem item) => item.Key == key);
				return (configItem.Sync, configItem.Optional);
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return (false, false);
			}
		}

		public (bool, bool) FindNetInfo(int index)
		{
			try
			{
				return (items[index].Sync, items[index].Optional);
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return (false, false);
			}
		}

		public object FindDefaultValue(string key)
		{
			try
			{
				return items.First((ConfigItem item) => item.Key == key).DefaultValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public object FindDefaultValue(int index)
		{
			try
			{
				return items[index].DefaultValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public bool MustBeSync(string key)
		{
			try
			{
				return items.First((ConfigItem item) => item.Key == key).Sync;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return true;
			}
		}

		public bool MustBeSync(int index)
		{
			try
			{
				return items[index].Sync;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return true;
			}
		}

		public bool SetItemValue(string key, object value)
		{
			ConfigItem configItem = items.First((ConfigItem item) => item.Key == key);
			if (!items.First((ConfigItem item) => item.Key == key).RequireRestart)
			{
				try
				{
					configItem.Value = value;
					return true;
				}
				catch (Exception ex)
				{
					LethalExpansion.Log.LogError((object)ex.Message);
					return false;
				}
			}
			return false;
		}

		public bool SetEntryValue(string key, object value)
		{
			try
			{
				entries.First((ConfigEntryBase item) => item.Definition.Key == key).BoxedValue = value;
				return true;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public bool SetItemValue(int index, string value, char type)
		{
			if (!items[index].RequireRestart)
			{
				try
				{
					switch (type)
					{
					case 'i':
						items[index].Value = int.Parse(value, CultureInfo.InvariantCulture);
						break;
					case 'f':
						items[index].Value = float.Parse(value, CultureInfo.InvariantCulture);
						break;
					case 'b':
						items[index].Value = bool.Parse(value);
						break;
					case 's':
						items[index].Value = value;
						break;
					}
					return true;
				}
				catch (Exception ex)
				{
					LethalExpansion.Log.LogError((object)ex.Message);
					return false;
				}
			}
			return false;
		}

		public bool SetEntryValue(int index, string value, char type)
		{
			try
			{
				switch (type)
				{
				case 'i':
					entries[index].BoxedValue = int.Parse(value);
					break;
				case 'f':
					entries[index].BoxedValue = float.Parse(value);
					break;
				case 'b':
					entries[index].BoxedValue = bool.Parse(value);
					break;
				case 's':
					entries[index].BoxedValue = value;
					break;
				}
				return true;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public (object, int) FindValueAndIndex(string key)
		{
			try
			{
				return (items.First((ConfigItem item) => item.Key == key).Value, items.FindIndex((ConfigItem item) => item.Key == key));
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return (null, -1);
			}
		}

		public int FindIndex(string key)
		{
			try
			{
				return items.FindIndex((ConfigItem item) => item.Key == key);
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return -1;
			}
		}

		public T FindItemValue<T>(string key)
		{
			try
			{
				ConfigItem configItem = items.First((ConfigItem item) => item.Key == key);
				if (configItem != null && configItem.Value is T)
				{
					return (T)configItem.Value;
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return default(T);
			}
		}

		public T FindItemValue<T>(int index)
		{
			try
			{
				ConfigItem configItem = items[index];
				if (configItem != null && configItem.Value is T)
				{
					return (T)configItem.Value;
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return default(T);
			}
		}

		public T FindEntryValue<T>(string key)
		{
			try
			{
				ConfigEntryBase val = entries.First((ConfigEntryBase item) => item.Definition.Key == key);
				if (val != null && val.BoxedValue is T)
				{
					return (T)val.BoxedValue;
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return default(T);
			}
		}

		public T FindEntryValue<T>(int index)
		{
			try
			{
				ConfigEntryBase val = entries[index];
				if (val != null && val.BoxedValue is T)
				{
					return (T)val.BoxedValue;
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return default(T);
			}
		}

		public bool SetItemValue<T>(string key, T value)
		{
			ConfigItem configItem = items.First((ConfigItem item) => item.Key == key);
			if (!configItem.RequireRestart)
			{
				try
				{
					if (configItem == null || !(configItem.Value is T))
					{
						LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
						throw new InvalidOperationException("Key not found or value is of incorrect type");
					}
					configItem.Value = value;
					return true;
				}
				catch (Exception ex)
				{
					LethalExpansion.Log.LogError((object)ex.Message);
					return false;
				}
			}
			return false;
		}

		public bool SetEntryValue<T>(string key, T value)
		{
			try
			{
				ConfigEntryBase val = entries.First((ConfigEntryBase item) => item.Definition.Key == key);
				if (val != null && val.BoxedValue is T)
				{
					val.BoxedValue = value;
					return true;
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public bool SetItemValue<T>(int index, T value)
		{
			if (!items[index].RequireRestart)
			{
				try
				{
					items[index].Value = value;
					return true;
				}
				catch (Exception ex)
				{
					LethalExpansion.Log.LogError((object)ex.Message);
					return false;
				}
			}
			return false;
		}

		public bool SetEntryValue<T>(int index, T value)
		{
			try
			{
				entries[index].BoxedValue = value;
				return true;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public (T, int) FindValueAndIndex<T>(string key)
		{
			try
			{
				ConfigItem configItem = items.First((ConfigItem item) => item.Key == key);
				if (configItem != null && configItem.Value is T)
				{
					return ((T)configItem.Value, items.FindIndex((ConfigItem item) => item.Key == key));
				}
				LethalExpansion.Log.LogError((object)"Key not found or value is of incorrect type");
				throw new InvalidOperationException("Key not found or value is of incorrect type");
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return (default(T), -1);
			}
		}

		public List<ConfigItem> GetAll()
		{
			try
			{
				return items;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public int GetCount()
		{
			try
			{
				return items.Count;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return -1;
			}
		}

		public int GetEntriesCount()
		{
			try
			{
				return entries.Count;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return -1;
			}
		}

		public object ReadConfigValue(string key)
		{
			try
			{
				return entries[FindIndex(key)].BoxedValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return null;
			}
		}

		public T ReadConfigValue<T>(string key)
		{
			try
			{
				return (T)entries[FindIndex(key)].BoxedValue;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return default(T);
			}
		}

		public bool WriteConfigValue(string key, object value)
		{
			try
			{
				int index = FindIndex(key);
				SetItemValue(index, value);
				entries[index].BoxedValue = value;
				return true;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}

		public bool WriteConfigValue<T>(string key, T value)
		{
			try
			{
				int index = FindIndex(key);
				SetItemValue(index, value);
				entries[index].BoxedValue = value;
				return true;
			}
			catch (Exception ex)
			{
				LethalExpansion.Log.LogError((object)ex.Message);
				return false;
			}
		}
	}
	public static class ModUtils
	{
		public static T[] RemoveElementFromArray<T>(T[] originalArray, int indexToRemove)
		{
			if (indexToRemove < 0 || indexToRemove >= originalArray.Length)
			{
				throw new ArgumentOutOfRangeException("indexToRemove");
			}
			T[] array = new T[originalArray.Length - 1];
			int i = 0;
			int num = 0;
			for (; i < originalArray.Length; i++)
			{
				if (i != indexToRemove)
				{
					array[num] = originalArray[i];
					num++;
				}
			}
			return array;
		}
	}
	public class NetworkPacketManager
	{
		public enum packetType
		{
			request = 0,
			data = 1,
			other = -1
		}

		private static NetworkPacketManager _instance;

		private ConcurrentDictionary<long, CancellationTokenSource> timeoutDictionary = new ConcurrentDictionary<long, CancellationTokenSource>();

		public static NetworkPacketManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new NetworkPacketManager();
				}
				return _instance;
			}
		}

		private NetworkPacketManager()
		{
		}

		public void sendPacket(packetType type, string header, string packet, long destination = -1L, bool waitForAnswer = true)
		{
			HUDManager.Instance.AddTextToChatOnServer($"[sync]{(int)type}|{((NetworkBehaviour)RoundManager.Instance).NetworkManager.LocalClientId}>{destination}|{header}={packet}[sync]", -1);
			if ((waitForAnswer && ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost && ConfigManager.Instance.FindItemValue<bool>("LoadModules")) || ConfigManager.Instance.FindItemValue<bool>("KickPlayerWithoutMod"))
			{
				StartTimeout(destination);
			}
		}

		public void sendPacket(packetType type, string header, string packet, long[] destinations, bool waitForAnswer = true)
		{
			for (int i = 0; i < destinations.Length; i++)
			{
				int num = (int)destinations[i];
				if (num != -1)
				{
					HUDManager.Instance.AddTextToChatOnServer($"[sync]{(int)type}|{((NetworkBehaviour)RoundManager.Instance).NetworkManager.LocalClientId}>{num}|{header}={packet}[sync]", -1);
					if ((waitForAnswer && ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost && ConfigManager.Instance.FindItemValue<bool>("LoadModules")) || ConfigManager.Instance.FindItemValue<bool>("KickPlayerWithoutMod"))
					{
						StartTimeout(num);
					}
				}
			}
		}

		public void StartTimeout(long id)
		{
			CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
			if (!timeoutDictionary.TryAdd(id, cancellationTokenSource))
			{
				return;
			}
			Task.Run(async delegate
			{
				try
				{
					await PacketTimeout(id, cancellationTokenSource.Token);
				}
				catch (OperationCanceledException)
				{
				}
				finally
				{
					timeoutDictionary.TryRemove(id, out var _);
				}
			});
		}

		public void CancelTimeout(long id)
		{
			if (timeoutDictionary.TryRemove(id, out var value))
			{
				value.Cancel();
			}
		}

		private async Task PacketTimeout(long id, CancellationToken token)
		{
			await Task.Delay(5000, token);
			if (token.IsCancellationRequested)
			{
			}
		}
	}
	public class PopupManager
	{
		private static PopupManager _instance;

		private List<PopupObject> popups = new List<PopupObject>();

		public static PopupManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new PopupManager();
				}
				return _instance;
			}
		}

		private PopupManager()
		{
		}

		public void InstantiatePopup(Scene sceneFocus, string title = "Popup", string content = "", string button1 = "Ok", string button2 = "Cancel", UnityAction button1Action = null, UnityAction button2Action = null, int titlesize = 24, int contentsize = 24, int button1size = 24, int button2size = 24)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			if (!((Scene)(ref sceneFocus)).isLoaded)
			{
				return;
			}
			GameObject[] rootGameObjects = ((Scene)(ref sceneFocus)).GetRootGameObjects();
			Canvas val = null;
			GameObject[] array = rootGameObjects;
			foreach (GameObject val2 in array)
			{
				val = val2.GetComponentInChildren<Canvas>();
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null || ((Component)val).gameObject.scene != sceneFocus)
			{
				GameObject val3 = new GameObject();
				((Object)val3).name = "Canvas";
				val = val3.AddComponent<Canvas>();
				SceneManager.MoveGameObjectToScene(((Component)val).gameObject, sceneFocus);
			}
			GameObject _tmp = Object.Instantiate<GameObject>(AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Prefabs/HUD/Popup.prefab"), ((Component)val).transform);
			if ((Object)(object)_tmp != (Object)null)
			{
				((Component)_tmp.transform.Find("DragAndDropSurface")).gameObject.AddComponent<SettingMenu_DragAndDrop>().rectTransform = _tmp.GetComponent<RectTransform>();
				((UnityEvent)((Component)_tmp.transform.Find("CloseButton")).gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					Object.Destroy((Object)(object)_tmp);
				});
				if (button1Action != null)
				{
					((UnityEvent)((Component)_tmp.transform.Find("Button1")).gameObject.GetComponent<Button>().onClick).AddListener(button1Action);
				}
				if (button2Action != null)
				{
					((UnityEvent)((Component)_tmp.transform.Find("Button2")).gameObject.GetComponent<Button>().onClick).AddListener(button2Action);
				}
				((UnityEvent)((Component)_tmp.transform.Find("Button1")).gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					Object.Destroy((Object)(object)_tmp);
				});
				((UnityEvent)((Component)_tmp.transform.Find("Button2")).gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					Object.Destroy((Object)(object)_tmp);
				});
				PopupObject popupObject = new PopupObject(_tmp, ((Component)_tmp.transform.Find("Title")).GetComponent<TMP_Text>(), ((Component)_tmp.transform.Find("Panel/MainContent")).GetComponent<TMP_Text>(), ((Component)_tmp.transform.Find("Button1/Text")).GetComponent<TMP_Text>(), ((Component)_tmp.transform.Find("Button2/Text")).GetComponent<TMP_Text>());
				popupObject.title.text = title;
				popupObject.title.fontSize = titlesize;
				popupObject.content.text = content;
				popupObject.content.fontSize = contentsize;
				popupObject.button1.text = button1;
				popupObject.button1.fontSize = button1size;
				popupObject.button2.text = button2;
				popupObject.button2.fontSize = button2size;
				popups.Add(popupObject);
			}
		}
	}
	public class PopupObject
	{
		public GameObject baseObject;

		public TMP_Text title;

		public TMP_Text content;

		public TMP_Text button1;

		public TMP_Text button2;

		public PopupObject(GameObject baseObject, TMP_Text title, TMP_Text content, TMP_Text button1, TMP_Text button2)
		{
			this.baseObject = baseObject;
			this.title = title;
			this.content = content;
			this.button1 = button1;
			this.button2 = button2;
		}
	}
	public class VersionChecker
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__1_0;

			internal void <CompareVersions>b__1_0()
			{
				Application.OpenURL("https://thunderstore.io/c/lethal-company/p/HolographicWings/LethalExpansion/");
			}
		}

		public static async Task CheckVersion()
		{
			HttpClient httpClient = new HttpClient();
			try
			{
				CompareVersions(await httpClient.GetStringAsync("https://raw.githubusercontent.com/HolographicWings/LethalExpansion/main/last.txt"));
			}
			catch (HttpRequestException val)
			{
				HttpRequestException val2 = val;
				HttpRequestException ex = val2;
				LethalExpansion.Log.LogError((object)((Exception)(object)ex).Message);
			}
			finally
			{
				((IDisposable)httpClient)?.Dispose();
			}
		}

		private static void CompareVersions(string onlineVersion)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005e: Expected O, but got Unknown
			if (!(LethalExpansion.ModVersion < Version.Parse(onlineVersion)))
			{
				return;
			}
			PopupManager instance = PopupManager.Instance;
			Scene sceneByName = SceneManager.GetSceneByName("MainMenu");
			string content = "Lethal Expansion is not up to date " + onlineVersion;
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					Application.OpenURL("https://thunderstore.io/c/lethal-company/p/HolographicWings/LethalExpansion/");
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			instance.InstantiatePopup(sceneByName, "Update", content, "Update", "Ignore", (UnityAction)obj);
		}
	}
}
namespace LethalExpansion.Utils.HUD
{
	public class SettingMenu_DragAndDrop : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		public UnityEvent onBeginDragEvent;

		public UnityEvent onDragEvent;

		public UnityEvent onEndDragEvent;

		public RectTransform rectTransform;

		private Canvas canvas;

		private void Awake()
		{
			if ((Object)(object)rectTransform == (Object)null)
			{
				rectTransform = ((Component)this).GetComponent<RectTransform>();
			}
			canvas = Object.FindFirstObjectByType<Canvas>();
		}

		public void OnBeginDrag(PointerEventData eventData)
		{
			if (onBeginDragEvent != null)
			{
				onBeginDragEvent.Invoke();
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			if (eventData != null && (Object)(object)rectTransform != (Object)null)
			{
				rectTransform.anchoredPosition = ClampToWindow(rectTransform.anchoredPosition + eventData.delta / canvas.scaleFactor);
				if (onDragEvent != null)
				{
					onDragEvent.Invoke();
				}
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			if (onEndDragEvent != null)
			{
				onEndDragEvent.Invoke();
			}
		}

		private Vector2 ClampToWindow(Vector2 position)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			float num = -260f;
			float num2 = 260f;
			float num3 = -60f;
			float num4 = 50f;
			float num5 = Mathf.Clamp(position.x, num, num2);
			float num6 = Mathf.Clamp(position.y, num3, num4);
			return new Vector2(num5, num6);
		}
	}
	public class SettingsMenu
	{
		private static SettingsMenu _instance;

		private bool initialized = false;

		private List<HUDSettingEntry> entries = new List<HUDSettingEntry>();

		public static SettingsMenu Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new SettingsMenu();
				}
				return _instance;
			}
		}

		private SettingsMenu()
		{
		}

		public void InitSettingsMenu()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Expected O, but got Unknown
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Expected O, but got Unknown
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Expected O, but got Unknown
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Expected O, but got Unknown
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0733: Unknown result type (might be due to invalid IL or missing references)
			//IL_073d: Expected O, but got Unknown
			//IL_0859: Unknown result type (might be due to invalid IL or missing references)
			//IL_0863: Expected O, but got Unknown
			//IL_08df: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e9: Expected O, but got Unknown
			//IL_0965: Unknown result type (might be due to invalid IL or missing references)
			//IL_096f: Expected O, but got Unknown
			entries = new List<HUDSettingEntry>();
			GameObject val = GameObject.Find("Canvas/MenuContainer");
			if ((Object)(object)val == (Object)null)
			{
				LethalExpansion.Log.LogError((object)"MenuContainer not found in the scene!");
				return;
			}
			RectTransform component = ((Component)val.transform.Find("MainButtons/HostButton")).GetComponent<RectTransform>();
			component.anchoredPosition += new Vector2(0f, 38.5f);
			RectTransform component2 = ((Component)val.transform.Find("MainButtons/JoinACrew")).GetComponent<RectTransform>();
			component2.anchoredPosition += new Vector2(0f, 38.5f);
			RectTransform component3 = ((Component)val.transform.Find("MainButtons/StartLAN")).GetComponent<RectTransform>();
			component3.anchoredPosition += new Vector2(0f, 38.5f);
			GameObject gameObject = ((Component)val.transform.Find("MainButtons/SettingsButton")).gameObject;
			RectTransform component4 = gameObject.GetComponent<RectTransform>();
			component4.anchoredPosition += new Vector2(0f, 38.5f);
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, val.transform);
			val2.transform.SetParent(val.transform.Find("MainButtons"));
			((Object)val2).name = "ModSettingsButton";
			((Component)val2.transform.Find("Text (TMP)")).GetComponent<TMP_Text>().text = "> Mod Settings";
			val2.GetComponent<RectTransform>().anchoredPosition = gameObject.GetComponent<RectTransform>().anchoredPosition - new Vector2(0f, 38.5f);
			GameObject ModSettingsPanel = Object.Instantiate<GameObject>(AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Prefabs/HUD/Settings/ModSettings.prefab"));
			GameObject val3 = AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Prefabs/HUD/Settings/SettingEntry.prefab");
			GameObject val4 = AssetBundlesManager.Instance.mainAssetBundle.LoadAsset<GameObject>("Assets/Mods/LethalExpansion/Prefabs/HUD/Settings/SettingCategory.prefab");
			ModSettingsPanel.transform.SetParent(val.transform);
			ModSettingsPanel.transform.localPosition = Vector3.zero;
			ModSettingsPanel.transform.localScale = Vector3.one;
			Button component5 = val2.GetComponent<Button>();
			component5.onClick = new ButtonClickedEvent();
			((UnityEvent)component5.onClick).AddListener((UnityAction)delegate
			{
				ModSettingsPanel.SetActive(true);
				GetSettings();
			});
			SettingMenu_DragAndDrop settingMenu_DragAndDrop = ((Component)ModSettingsPanel.transform.Find("DragAndDropSurface")).gameObject.AddComponent<SettingMenu_DragAndDrop>();
			settingMenu_DragAndDrop.rectTransform = ModSettingsPanel.GetComponent<RectTransform>();
			Button component6 = ((Component)ModSettingsPanel.transform.Find("CloseButton")).GetComponent<Button>();
			Button component7 = ((Component)ModSettingsPanel.transform.Find("ApplyButton")).GetComponent<Button>();
			Button component8 = ((Component)ModSettingsPanel.transform.Find("CancelButton")).GetComponent<Button>();
			((UnityEvent)component6.onClick).AddListener((UnityAction)delegate
			{
				ModSettingsPanel.SetActive(false);
			});
			((UnityEvent)component7.onClick).AddListener((UnityAction)delegate
			{
				ApplySettings();
				ModSettingsPanel.SetActive(false);
			});
			((UnityEvent)component8.onClick).AddListener((UnityAction)delegate
			{
				ModSettingsPanel.SetActive(false);
			});
			GameObject gameObject2 = ((Component)ModSettingsPanel.transform.Find("Scroll View/Viewport/ModSettingsContent")).gameObject;
			Button component9 = ((Component)gameObject2.transform.Find("AllDefaultButton")).GetComponent<Button>();
			((UnityEvent)component9.onClick).AddListener((UnityAction)delegate
			{
				ResetAllSettings();
			});
			RectTransform component10 = gameObject2.GetComponent<RectTransform>();
			GameObject gameObject3 = ((Component)gameObject2.transform.Find("TooltipPanel")).gameObject;
			TooltipHandler.ModSettingsToolTipPanel = gameObject3.GetComponent<RectTransform>();
			TooltipHandler.ModSettingsToolTipPanelDescription = ((Component)gameObject3.transform.Find("Description")).GetComponent<TMP_Text>();
			TooltipHandler.ModSettingsToolTipPanelNetInfo = ((Component)gameObject3.transform.Find("NetInfo")).GetComponent<TMP_Text>();
			int num = -15;
			string text = string.Empty;
			foreach (ConfigItem item in ConfigManager.Instance.GetAll())
			{
				if (item.Tab != text)
				{
					GameObject val5 = Object.Instantiate<GameObject>(val4, gameObject2.transform);
					((Component)val5.transform.Find("Text")).GetComponent<TMP_Text>().text = item.Tab + ":";
					val5.GetComponent<RectTransform>().anchoredPosition = n

BepInEx/plugins/LethalSDK.dll

Decompiled 8 months 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.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using DunGen;
using DunGen.Adapters;
using GameNetcodeStuff;
using LethalSDK.Component;
using LethalSDK.ScriptableObjects;
using LethalSDK.Utils;
using Unity.Netcode;
using UnityEditor;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalSDK")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalSDK")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4d234a4d-c807-438a-b717-4c6d77706054")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AssetModificationProcessor : AssetPostprocessor
{
	private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
	{
		foreach (string assetPath in importedAssets)
		{
			ProcessAsset(assetPath);
		}
		foreach (string assetPath2 in movedAssets)
		{
			ProcessAsset(assetPath2);
		}
	}

	private static void ProcessAsset(string assetPath)
	{
		if (assetPath.Contains("NavMesh-Environment"))
		{
			AssetDatabase.RenameAsset(assetPath, (SelectionLogger.name != string.Empty) ? (SelectionLogger.name + "NavMesh") : "New NavMesh");
		}
		if (assetPath.Contains("New Terrain"))
		{
			AssetDatabase.RenameAsset(assetPath, (SelectionLogger.name != string.Empty) ? SelectionLogger.name : "New Terrain");
		}
		if (assetPath.ToLower().StartsWith("assets/mods/") && assetPath.Split(new char[1] { '/' }).Length > 3 && !assetPath.ToLower().EndsWith(".unity") && !assetPath.ToLower().Contains("/scenes"))
		{
			AssetImporter atPath = AssetImporter.GetAtPath(assetPath);
			if ((Object)(object)atPath != (Object)null)
			{
				string text2 = (atPath.assetBundleName = ExtractBundleNameFromPath(assetPath));
				atPath.assetBundleVariant = "lem";
				Debug.Log((object)(assetPath + " asset moved to " + text2 + " asset bundle."));
			}
			if (assetPath != "Assets/Mods/" + assetPath.ToLower().Replace("assets/mods/", string.Empty).RemoveNonAlphanumeric(4))
			{
				AssetDatabase.MoveAsset(assetPath, "Assets/Mods/" + assetPath.ToLower().Replace("assets/mods/", string.Empty).RemoveNonAlphanumeric(4));
			}
		}
		else
		{
			AssetImporter atPath2 = AssetImporter.GetAtPath(assetPath);
			if ((Object)(object)atPath2 != (Object)null)
			{
				atPath2.assetBundleName = null;
				Debug.Log((object)(assetPath + " asset removed from asset bundle."));
			}
		}
	}

	public static string ExtractBundleNameFromPath(string path)
	{
		string[] array = path.Split(new char[1] { '/' });
		if (array.Length > 3)
		{
			return array[2].ToLower();
		}
		return "";
	}
}
[InitializeOnLoad]
public class SelectionLogger
{
	public static string name;

	static SelectionLogger()
	{
		Selection.selectionChanged = (Action)Delegate.Combine(Selection.selectionChanged, new Action(OnSelectionChanged));
	}

	private static void OnSelectionChanged()
	{
		if ((Object)(object)Selection.activeGameObject != (Object)null)
		{
			name = ((Object)GetRootParent(Selection.activeGameObject)).name;
		}
		else
		{
			name = string.Empty;
		}
	}

	public static GameObject GetRootParent(GameObject obj)
	{
		if ((Object)(object)obj != (Object)null && (Object)(object)obj.transform.parent != (Object)null)
		{
			return GetRootParent(((Component)obj.transform.parent).gameObject);
		}
		return obj;
	}
}
[InitializeOnLoad]
public class AssetBundleVariantAssigner
{
	static AssetBundleVariantAssigner()
	{
		AssignVariantToAssetBundles();
	}

	[InitializeOnLoadMethod]
	private static void AssignVariantToAssetBundles()
	{
		string[] allAssetBundleNames = AssetDatabase.GetAllAssetBundleNames();
		string[] array = allAssetBundleNames;
		foreach (string text in array)
		{
			if (!text.Contains("."))
			{
				string[] assetPathsFromAssetBundle = AssetDatabase.GetAssetPathsFromAssetBundle(text);
				string[] array2 = assetPathsFromAssetBundle;
				foreach (string text2 in array2)
				{
					AssetImporter.GetAtPath(text2).SetAssetBundleNameAndVariant(text, "lem");
				}
				Debug.Log((object)("File extention added to AssetBundle: " + text));
			}
		}
		AssetDatabase.SaveAssets();
		string text3 = "Assets/AssetBundles";
		if (!Directory.Exists(text3))
		{
			Debug.LogError((object)("Le dossier n'existe pas : " + text3));
			return;
		}
		string[] files = Directory.GetFiles(text3);
		string[] array3 = files;
		foreach (string text4 in array3)
		{
			if (Path.GetExtension(text4) == "" && Path.GetFileName(text4) != "AssetBundles")
			{
				string path = text4 + ".meta";
				string text5 = text4 + ".manifest";
				string path2 = text5 + ".meta";
				File.Delete(text4);
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				if (File.Exists(text5))
				{
					File.Delete(text5);
				}
				if (File.Exists(path2))
				{
					File.Delete(path2);
				}
				Debug.Log((object)("Fichier supprimé : " + text4));
			}
		}
		AssetDatabase.Refresh();
	}
}
public class CubemapTextureBuilder : EditorWindow
{
	private Texture2D[] textures = (Texture2D[])(object)new Texture2D[6];

	private string[] labels = new string[6] { "Right", "Left", "Top", "Bottom", "Front", "Back" };

	private TextureFormat[] HDRFormats;

	private Vector2Int[] placementRects;

	[MenuItem("LethalSDK/Cubemap Builder", false, 100)]
	public static void OpenWindow()
	{
		EditorWindow.GetWindow<CubemapTextureBuilder>();
	}

	private Texture2D UpscaleTexture(Texture2D original, int targetWidth, int targetHeight)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		RenderTexture val = (RenderTexture.active = RenderTexture.GetTemporary(targetWidth, targetHeight));
		Graphics.Blit((Texture)(object)original, val);
		Texture2D val2 = new Texture2D(targetWidth, targetHeight);
		val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), 0, 0);
		val2.Apply();
		RenderTexture.ReleaseTemporary(val);
		return val2;
	}

	private void OnGUI()
	{
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Expected O, but got Unknown
		for (int i = 0; i < 6; i++)
		{
			ref Texture2D reference = ref textures[i];
			Object obj = EditorGUILayout.ObjectField(labels[i], (Object)(object)textures[i], typeof(Texture2D), false, Array.Empty<GUILayoutOption>());
			reference = (Texture2D)(object)((obj is Texture2D) ? obj : null);
		}
		if (!GUILayout.Button("Build Cubemap", Array.Empty<GUILayoutOption>()))
		{
			return;
		}
		if (textures.Any((Texture2D t) => (Object)(object)t == (Object)null))
		{
			EditorUtility.DisplayDialog("Cubemap Builder Error", "One or more texture is missing.", "Ok");
			return;
		}
		int size = ((Texture)textures[0]).width;
		if (textures.Any((Texture2D t) => ((Texture)t).width != size || ((Texture)t).height != size))
		{
			EditorUtility.DisplayDialog("Cubemap Builder Error", "All the textures need to be the same size and square.", "Ok");
			return;
		}
		bool flag = HDRFormats.Any((TextureFormat f) => f == textures[0].format);
		string[] array = textures.Select((Texture2D t) => AssetDatabase.GetAssetPath((Object)(object)t)).ToArray();
		string text = EditorUtility.SaveFilePanel("Save Cubemap", Path.GetDirectoryName(array[0]), "Cubemap", flag ? "exr" : "png");
		if (!string.IsNullOrEmpty(text))
		{
			bool[] array2 = textures.Select((Texture2D t) => ((Texture)t).isReadable).ToArray();
			TextureImporter[] array3 = array.Select(delegate(string p)
			{
				AssetImporter atPath2 = AssetImporter.GetAtPath(p);
				return (TextureImporter)(object)((atPath2 is TextureImporter) ? atPath2 : null);
			}).ToArray();
			TextureImporter[] array4 = array3;
			foreach (TextureImporter val in array4)
			{
				val.isReadable = true;
			}
			AssetDatabase.Refresh();
			string[] array5 = array;
			foreach (string text2 in array5)
			{
				AssetDatabase.ImportAsset(text2);
			}
			Texture2D val2 = new Texture2D(size * 4, size * 3, (TextureFormat)(flag ? 20 : 4), false);
			for (int l = 0; l < 6; l++)
			{
				val2.SetPixels(((Vector2Int)(ref placementRects[l])).x * size, ((Vector2Int)(ref placementRects[l])).y * size, size, size, textures[l].GetPixels(0));
			}
			val2.Apply(false);
			byte[] bytes = (flag ? ImageConversion.EncodeToEXR(val2) : ImageConversion.EncodeToPNG(val2));
			File.WriteAllBytes(text, bytes);
			Object.Destroy((Object)(object)val2);
			for (int m = 0; m < 6; m++)
			{
				array3[m].isReadable = array2[m];
			}
			text = text.Remove(0, Application.dataPath.Length - 6);
			AssetDatabase.ImportAsset(text);
			AssetImporter atPath = AssetImporter.GetAtPath(text);
			TextureImporter val3 = (TextureImporter)(object)((atPath is TextureImporter) ? atPath : null);
			val3.textureShape = (TextureImporterShape)2;
			val3.sRGBTexture = false;
			val3.generateCubemap = (TextureImporterGenerateCubemap)5;
			string[] array6 = array;
			foreach (string text3 in array6)
			{
				AssetDatabase.ImportAsset(text3);
			}
			AssetDatabase.ImportAsset(text);
			AssetDatabase.Refresh();
		}
	}

	public CubemapTextureBuilder()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_009a: 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_00a8: 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)
		TextureFormat[] array = new TextureFormat[9];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		HDRFormats = (TextureFormat[])(object)array;
		placementRects = (Vector2Int[])(object)new Vector2Int[6]
		{
			new Vector2Int(2, 1),
			new Vector2Int(0, 1),
			new Vector2Int(1, 2),
			new Vector2Int(1, 0),
			new Vector2Int(1, 1),
			new Vector2Int(3, 1)
		};
		((EditorWindow)this)..ctor();
	}
}
public class PlayerShip : MonoBehaviour
{
	public readonly Vector3 shipPosition = new Vector3(-17.5f, 5.75f, -16.55f);

	private void Start()
	{
		Object.Destroy((Object)(object)this);
	}
}
[CustomEditor(typeof(PlayerShip))]
public class PlayerShipEditor : Editor
{
	public override void OnInspectorGUI()
	{
		//IL_001a: 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_0036: Unknown result type (might be due to invalid IL or missing references)
		((Editor)this).OnInspectorGUI();
		PlayerShip playerShip = (PlayerShip)(object)((Editor)this).target;
		if (((Component)playerShip).transform.position != playerShip.shipPosition)
		{
			((Component)playerShip).transform.position = playerShip.shipPosition;
		}
	}
}
namespace LethalSDK.ScriptableObjects
{
	[CreateAssetMenu(fileName = "AssetBank", menuName = "LethalSDK/Asset Bank")]
	public class AssetBank : ScriptableObject
	{
		[Header("Audio Clips")]
		[SerializeField]
		private AudioClipInfoPair[] _audioClips = new AudioClipInfoPair[0];

		[SerializeField]
		private PlanetPrefabInfoPair[] _planetPrefabs = new PlanetPrefabInfoPair[0];

		[SerializeField]
		private PrefabInfoPair[] _networkPrefabs = new PrefabInfoPair[0];

		[HideInInspector]
		public string serializedAudioClips;

		[HideInInspector]
		public string serializedPlanetPrefabs;

		[HideInInspector]
		public string serializedNetworkPrefabs;

		private void OnValidate()
		{
			for (int i = 0; i < _audioClips.Length; i++)
			{
				_audioClips[i].AudioClipName = _audioClips[i].AudioClipName.RemoveNonAlphanumeric(1);
				_audioClips[i].AudioClipPath = _audioClips[i].AudioClipPath.RemoveNonAlphanumeric(4);
			}
			for (int j = 0; j < _planetPrefabs.Length; j++)
			{
				_planetPrefabs[j].PlanetPrefabName = _planetPrefabs[j].PlanetPrefabName.RemoveNonAlphanumeric(1);
				_planetPrefabs[j].PlanetPrefabPath = _planetPrefabs[j].PlanetPrefabPath.RemoveNonAlphanumeric(4);
			}
			for (int k = 0; k < _networkPrefabs.Length; k++)
			{
				_networkPrefabs[k].PrefabName = _networkPrefabs[k].PrefabName.RemoveNonAlphanumeric(1);
				_networkPrefabs[k].PrefabPath = _networkPrefabs[k].PrefabPath.RemoveNonAlphanumeric(4);
			}
			serializedAudioClips = string.Join(";", _audioClips.Select((AudioClipInfoPair p) => ((p.AudioClipName.Length != 0) ? p.AudioClipName : (((Object)(object)p.AudioClip != (Object)null) ? ((Object)p.AudioClip).name : "")) + "," + AssetDatabase.GetAssetPath((Object)(object)p.AudioClip)));
			serializedPlanetPrefabs = string.Join(";", _planetPrefabs.Select((PlanetPrefabInfoPair p) => ((p.PlanetPrefabName.Length != 0) ? p.PlanetPrefabName : (((Object)(object)p.PlanetPrefab != (Object)null) ? ((Object)p.PlanetPrefab).name : "")) + "," + AssetDatabase.GetAssetPath((Object)(object)p.PlanetPrefab)));
			serializedNetworkPrefabs = string.Join(";", _networkPrefabs.Select((PrefabInfoPair p) => ((p.PrefabName.Length != 0) ? p.PrefabName : (((Object)(object)p.Prefab != (Object)null) ? ((Object)p.Prefab).name : "")) + "," + AssetDatabase.GetAssetPath((Object)(object)p.Prefab)));
		}

		public AudioClipInfoPair[] AudioClips()
		{
			if (serializedAudioClips != null)
			{
				return (from s in serializedAudioClips.Split(new char[1] { ';' })
					select s.Split(new char[1] { ',' }) into split
					where split.Length == 2
					select new AudioClipInfoPair(split[0], split[1])).ToArray();
			}
			return new AudioClipInfoPair[0];
		}

		public bool HaveAudioClip(string audioClipName)
		{
			if (serializedAudioClips != null)
			{
				return AudioClips().Any((AudioClipInfoPair a) => a.AudioClipName == audioClipName);
			}
			return false;
		}

		public string AudioClipPath(string audioClipName)
		{
			if (serializedAudioClips != null)
			{
				return AudioClips().First((AudioClipInfoPair c) => c.AudioClipName == audioClipName).AudioClipPath;
			}
			return string.Empty;
		}

		public Dictionary<string, string> AudioClipsDictionary()
		{
			if (serializedAudioClips != null)
			{
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				AudioClipInfoPair[] audioClips = _audioClips;
				for (int i = 0; i < audioClips.Length; i++)
				{
					AudioClipInfoPair audioClipInfoPair = audioClips[i];
					dictionary.Add(audioClipInfoPair.AudioClipName, audioClipInfoPair.AudioClipPath);
				}
				return dictionary;
			}
			return new Dictionary<string, string>();
		}

		public PlanetPrefabInfoPair[] PlanetPrefabs()
		{
			if (serializedPlanetPrefabs != null)
			{
				return (from s in serializedPlanetPrefabs.Split(new char[1] { ';' })
					select s.Split(new char[1] { ',' }) into split
					where split.Length == 2
					select new PlanetPrefabInfoPair(split[0], split[1])).ToArray();
			}
			return new PlanetPrefabInfoPair[0];
		}

		public bool HavePlanetPrefabs(string planetPrefabName)
		{
			if (serializedPlanetPrefabs != null)
			{
				return PlanetPrefabs().Any((PlanetPrefabInfoPair a) => a.PlanetPrefabName == planetPrefabName);
			}
			return false;
		}

		public string PlanetPrefabsPath(string planetPrefabName)
		{
			if (serializedPlanetPrefabs != null)
			{
				return PlanetPrefabs().First((PlanetPrefabInfoPair c) => c.PlanetPrefabName == planetPrefabName).PlanetPrefabPath;
			}
			return string.Empty;
		}

		public Dictionary<string, string> PlanetPrefabsDictionary()
		{
			if (serializedPlanetPrefabs != null)
			{
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				PlanetPrefabInfoPair[] planetPrefabs = _planetPrefabs;
				for (int i = 0; i < planetPrefabs.Length; i++)
				{
					PlanetPrefabInfoPair planetPrefabInfoPair = planetPrefabs[i];
					dictionary.Add(planetPrefabInfoPair.PlanetPrefabName, planetPrefabInfoPair.PlanetPrefabPath);
				}
				return dictionary;
			}
			return new Dictionary<string, string>();
		}

		public PrefabInfoPair[] NetworkPrefabs()
		{
			if (serializedNetworkPrefabs != null)
			{
				return (from s in serializedNetworkPrefabs.Split(new char[1] { ';' })
					select s.Split(new char[1] { ',' }) into split
					where split.Length == 2
					select new PrefabInfoPair(split[0], split[1])).ToArray();
			}
			return new PrefabInfoPair[0];
		}

		public bool HaveNetworkPrefabs(string networkPrefabName)
		{
			if (serializedNetworkPrefabs != null)
			{
				return NetworkPrefabs().Any((PrefabInfoPair a) => a.PrefabName == networkPrefabName);
			}
			return false;
		}

		public string NetworkPrefabsPath(string networkPrefabName)
		{
			if (serializedNetworkPrefabs != null)
			{
				return NetworkPrefabs().First((PrefabInfoPair c) => c.PrefabName == networkPrefabName).PrefabPath;
			}
			return string.Empty;
		}

		public Dictionary<string, string> NetworkPrefabsDictionary()
		{
			if (serializedNetworkPrefabs != null)
			{
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				PrefabInfoPair[] networkPrefabs = _networkPrefabs;
				for (int i = 0; i < networkPrefabs.Length; i++)
				{
					PrefabInfoPair prefabInfoPair = networkPrefabs[i];
					dictionary.Add(prefabInfoPair.PrefabName, prefabInfoPair.PrefabPath);
				}
				return dictionary;
			}
			return new Dictionary<string, string>();
		}
	}
	[CreateAssetMenu(fileName = "ModManifest", menuName = "LethalSDK/Mod Manifest")]
	public class ModManifest : ScriptableObject
	{
		public string modName = "New Mod";

		[Space]
		[SerializeField]
		private SerializableVersion version = new SerializableVersion(0, 0, 0, 0);

		[HideInInspector]
		public string serializedVersion;

		[Space]
		public string author = "Author";

		[Space]
		[TextArea(5, 15)]
		public string description = "Mod Description";

		[Space]
		[Header("Content")]
		public Scrap[] scraps = new Scrap[0];

		public Moon[] moons = new Moon[0];

		[Space]
		public AssetBank assetBank;

		private void OnValidate()
		{
			serializedVersion = version.ToString();
		}

		public SerializableVersion GetVersion()
		{
			int[] array = ((serializedVersion != null) ? serializedVersion.Split(new char[1] { '.' }).Select(int.Parse).ToArray() : new int[4]);
			return new SerializableVersion(array[0], array[1], array[2], array[3]);
		}
	}
	[CreateAssetMenu(fileName = "New Moon", menuName = "LethalSDK/Moon")]
	public class Moon : ScriptableObject
	{
		public string MoonName = "NewMoon";

		public string[] RequiredBundles;

		public string[] IncompatibleBundles;

		public bool IsEnabled = true;

		public bool IsHidden = false;

		public bool IsLocked = false;

		[Header("Info")]
		public string OrbitPrefabName = "Moon1";

		public bool SpawnEnemiesAndScrap = true;

		public string PlanetName = "New Moon";

		public GameObject MainPrefab;

		[TextArea(5, 15)]
		public string PlanetDescription;

		public VideoClip PlanetVideo;

		public string RiskLevel = "X";

		[Range(0f, 16f)]
		public float TimeToArrive = 1f;

		[Header("Time")]
		[Range(0.1f, 5f)]
		public float DaySpeedMultiplier = 1f;

		public bool PlanetHasTime = true;

		[SerializeField]
		private RandomWeatherPair[] _RandomWeatherTypes = new RandomWeatherPair[6]
		{
			new RandomWeatherPair(LevelWeatherType.None, 0, 0),
			new RandomWeatherPair(LevelWeatherType.Rainy, 0, 0),
			new RandomWeatherPair(LevelWeatherType.Stormy, 1, 0),
			new RandomWeatherPair(LevelWeatherType.Foggy, 1, 0),
			new RandomWeatherPair(LevelWeatherType.Flooded, -4, 5),
			new RandomWeatherPair(LevelWeatherType.Eclipsed, 1, 0)
		};

		public bool OverwriteWeather = false;

		public LevelWeatherType OverwriteWeatherType = LevelWeatherType.None;

		[Header("Route")]
		public string RouteWord = "newmoon";

		public int RoutePrice;

		public string BoughtComment = "Please enjoy your flight.";

		[Header("Dungeon")]
		[Range(1f, 5f)]
		public float FactorySizeMultiplier = 1f;

		public int FireExitsAmountOverwrite = 1;

		[SerializeField]
		private DungeonFlowPair[] _DungeonFlowTypes = new DungeonFlowPair[2]
		{
			new DungeonFlowPair(0, 300),
			new DungeonFlowPair(1, 1)
		};

		[SerializeField]
		private SpawnableScrapPair[] _SpawnableScrap = new SpawnableScrapPair[19]
		{
			new SpawnableScrapPair("Cog1", 80),
			new SpawnableScrapPair("EnginePart1", 90),
			new SpawnableScrapPair("FishTestProp", 12),
			new SpawnableScrapPair("MetalSheet", 88),
			new SpawnableScrapPair("FlashLaserPointer", 4),
			new SpawnableScrapPair("BigBolt", 80),
			new SpawnableScrapPair("BottleBin", 19),
			new SpawnableScrapPair("Ring", 3),
			new SpawnableScrapPair("SteeringWheel", 32),
			new SpawnableScrapPair("MoldPan", 5),
			new SpawnableScrapPair("EggBeater", 10),
			new SpawnableScrapPair("PickleJar", 10),
			new SpawnableScrapPair("DustPan", 32),
			new SpawnableScrapPair("Airhorn", 3),
			new SpawnableScrapPair("ClownHorn", 3),
			new SpawnableScrapPair("CashRegister", 3),
			new SpawnableScrapPair("Candy", 2),
			new SpawnableScrapPair("GoldBar", 1),
			new SpawnableScrapPair("YieldSign", 6)
		};

		[Range(0f, 100f)]
		public int MinScrap = 8;

		[Range(0f, 100f)]
		public int MaxScrap = 12;

		public string LevelAmbienceClips = "Level1TypeAmbience";

		[Range(0f, 30f)]
		public int MaxEnemyPowerCount = 4;

		[SerializeField]
		private SpawnableEnemiesPair[] _Enemies = new SpawnableEnemiesPair[8]
		{
			new SpawnableEnemiesPair("Centipede", 51),
			new SpawnableEnemiesPair("SandSpider", 58),
			new SpawnableEnemiesPair("HoarderBug", 28),
			new SpawnableEnemiesPair("Flowerman", 13),
			new SpawnableEnemiesPair("Crawler", 16),
			new SpawnableEnemiesPair("Blob", 31),
			new SpawnableEnemiesPair("DressGirl", 1),
			new SpawnableEnemiesPair("Puffer", 28)
		};

		public AnimationCurve EnemySpawnChanceThroughoutDay = CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0015411376953125,\"value\":-3.0,\"inSlope\":19.556997299194337,\"outSlope\":19.556997299194337,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.0,\"outWeight\":0.12297855317592621},{\"serializedVersion\":\"3\",\"time\":0.4575331211090088,\"value\":4.796203136444092,\"inSlope\":24.479534149169923,\"outSlope\":24.479534149169923,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.396077424287796,\"outWeight\":0.35472238063812258},{\"serializedVersion\":\"3\",\"time\":0.7593884468078613,\"value\":4.973001480102539,\"inSlope\":2.6163148880004885,\"outSlope\":2.6163148880004885,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.2901076376438141,\"outWeight\":0.5360636115074158},{\"serializedVersion\":\"3\",\"time\":1.0,\"value\":15.0,\"inSlope\":35.604026794433597,\"outSlope\":35.604026794433597,\"tangentMode\":0,\"weightedMode\":1,\"inWeight\":0.04912583902478218,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}");

		[Range(0f, 30f)]
		public float SpawnProbabilityRange = 4f;

		[Header("Outside")]
		[SerializeField]
		private SpawnableMapObjectPair[] _SpawnableMapObjects = new SpawnableMapObjectPair[2]
		{
			new SpawnableMapObjectPair("Landmine", spawnFacingAwayFromWall: false, CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":-0.003082275390625,\"value\":0.0,\"inSlope\":0.23179344832897187,\"outSlope\":0.23179344832897187,\"tangentMode\":0,\"weightedMode\":2,\"inWeight\":0.0,\"outWeight\":0.27936428785324099},{\"serializedVersion\":\"3\",\"time\":0.8171924352645874,\"value\":1.7483322620391846,\"inSlope\":7.064207077026367,\"outSlope\":7.064207077026367,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.2631833553314209,\"outWeight\":0.6898177862167358},{\"serializedVersion\":\"3\",\"time\":1.0002186298370362,\"value\":11.760997772216797,\"inSlope\":968.80810546875,\"outSlope\":968.80810546875,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.029036391526460649,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableMapObjectPair("TurretContainer", spawnFacingAwayFromWall: true, CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":0.354617178440094,\"outSlope\":0.354617178440094,\"tangentMode\":0,\"weightedMode\":2,\"inWeight\":0.0,\"outWeight\":0.0},{\"serializedVersion\":\"3\",\"time\":0.9190289974212647,\"value\":1.0005745887756348,\"inSlope\":Infinity,\"outSlope\":1.7338485717773438,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.0,\"outWeight\":0.6534967422485352},{\"serializedVersion\":\"3\",\"time\":1.0038425922393799,\"value\":7.198680877685547,\"inSlope\":529.4945068359375,\"outSlope\":529.4945068359375,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.14589552581310273,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}"))
		};

		[SerializeField]
		private SpawnableOutsideObjectPair[] _SpawnableOutsideObjects = new SpawnableOutsideObjectPair[7]
		{
			new SpawnableOutsideObjectPair("LargeRock1", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":0.0,\"outSlope\":0.0,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.0,\"outWeight\":0.0},{\"serializedVersion\":\"3\",\"time\":0.7571572661399841,\"value\":0.6448163986206055,\"inSlope\":2.974250078201294,\"outSlope\":2.974250078201294,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.3333333432674408,\"outWeight\":0.3333333432674408},{\"serializedVersion\":\"3\",\"time\":0.9995536804199219,\"value\":5.883961200714111,\"inSlope\":65.30631256103516,\"outSlope\":65.30631256103516,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.12097536772489548,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("LargeRock2", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":0.0,\"outSlope\":0.0,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.0,\"outWeight\":0.0},{\"serializedVersion\":\"3\",\"time\":0.7562879920005798,\"value\":1.2308543920516968,\"inSlope\":5.111926555633545,\"outSlope\":5.111926555633545,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.3333333432674408,\"outWeight\":0.21955738961696626},{\"serializedVersion\":\"3\",\"time\":1.0010795593261719,\"value\":7.59307336807251,\"inSlope\":92.0470199584961,\"outSlope\":92.0470199584961,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.05033162236213684,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("LargeRock3", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":0.0,\"outSlope\":0.0,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.0,\"outWeight\":0.0},{\"serializedVersion\":\"3\",\"time\":0.9964686632156372,\"value\":2.0009398460388185,\"inSlope\":6.82940673828125,\"outSlope\":6.82940673828125,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.06891261041164398,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("LargeRock4", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":0.0,\"outSlope\":0.0,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.0,\"outWeight\":0.0},{\"serializedVersion\":\"3\",\"time\":0.9635604619979858,\"value\":2.153383493423462,\"inSlope\":6.251225471496582,\"outSlope\":6.251225471496582,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.07428120821714401,\"outWeight\":0.3333333432674408},{\"serializedVersion\":\"3\",\"time\":0.9995394349098206,\"value\":5.0,\"inSlope\":15.746581077575684,\"outSlope\":15.746581077575684,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.06317413598299027,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("TreeLeafless1", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":1.6912956237792969,\"outSlope\":1.6912956237792969,\"tangentMode\":0,\"weightedMode\":2,\"inWeight\":0.0,\"outWeight\":0.27726083993911745},{\"serializedVersion\":\"3\",\"time\":0.776531994342804,\"value\":6.162014007568359,\"inSlope\":30.075166702270509,\"outSlope\":30.075166702270509,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.15920747816562653,\"outWeight\":0.5323987007141113},{\"serializedVersion\":\"3\",\"time\":1.0002281665802003,\"value\":38.093849182128909,\"inSlope\":1448.839111328125,\"outSlope\":1448.839111328125,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.0620061457157135,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("SmallGreyRocks1", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":1.6912956237792969,\"outSlope\":1.6912956237792969,\"tangentMode\":0,\"weightedMode\":2,\"inWeight\":0.0,\"outWeight\":0.27726083993911745},{\"serializedVersion\":\"3\",\"time\":0.802714467048645,\"value\":1.5478605031967164,\"inSlope\":9.096116065979004,\"outSlope\":9.096116065979004,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.15920747816562653,\"outWeight\":0.58766108751297},{\"serializedVersion\":\"3\",\"time\":1.0002281665802003,\"value\":14.584033966064454,\"inSlope\":1244.9173583984375,\"outSlope\":1244.9173583984375,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.054620321840047839,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}")),
			new SpawnableOutsideObjectPair("GiantPumpkin", CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":0.0,\"inSlope\":1.6912956237792969,\"outSlope\":1.6912956237792969,\"tangentMode\":0,\"weightedMode\":2,\"inWeight\":0.0,\"outWeight\":0.27726083993911745},{\"serializedVersion\":\"3\",\"time\":0.8832725882530212,\"value\":0.5284063816070557,\"inSlope\":3.2962090969085695,\"outSlope\":29.38977813720703,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.19772815704345704,\"outWeight\":0.8989489078521729},{\"serializedVersion\":\"3\",\"time\":0.972209095954895,\"value\":6.7684478759765629,\"inSlope\":140.27394104003907,\"outSlope\":140.27394104003907,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.39466607570648196,\"outWeight\":0.47049039602279665},{\"serializedVersion\":\"3\",\"time\":1.0002281665802003,\"value\":23.0,\"inSlope\":579.3037109375,\"outSlope\":14.8782377243042,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.648808479309082,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}"))
		};

		[Range(0f, 30f)]
		public int MaxOutsideEnemyPowerCount = 8;

		[Range(0f, 30f)]
		public int MaxDaytimeEnemyPowerCount = 5;

		[SerializeField]
		private SpawnableEnemiesPair[] _OutsideEnemies = new SpawnableEnemiesPair[3]
		{
			new SpawnableEnemiesPair("MouthDog", 75),
			new SpawnableEnemiesPair("ForestGiant", 0),
			new SpawnableEnemiesPair("SandWorm", 56)
		};

		[SerializeField]
		private SpawnableEnemiesPair[] _DaytimeEnemies = new SpawnableEnemiesPair[3]
		{
			new SpawnableEnemiesPair("RedLocustBees", 22),
			new SpawnableEnemiesPair("Doublewing", 74),
			new SpawnableEnemiesPair("DocileLocustBees", 52)
		};

		public AnimationCurve OutsideEnemySpawnChanceThroughDay = CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":-7.736962288618088e-7,\"value\":-2.996999979019165,\"inSlope\":Infinity,\"outSlope\":0.5040292143821716,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.0,\"outWeight\":0.08937685936689377},{\"serializedVersion\":\"3\",\"time\":0.7105481624603272,\"value\":-0.6555822491645813,\"inSlope\":9.172262191772461,\"outSlope\":9.172262191772461,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.3333333432674408,\"outWeight\":0.7196550369262695},{\"serializedVersion\":\"3\",\"time\":1.0052626132965088,\"value\":5.359400749206543,\"inSlope\":216.42247009277345,\"outSlope\":11.374387741088868,\"tangentMode\":0,\"weightedMode\":3,\"inWeight\":0.044637180864810947,\"outWeight\":0.48315444588661196}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}");

		public AnimationCurve DaytimeEnemySpawnChanceThroughDay = CurveContainer.DeserializeCurve("{\"curve\":{\"serializedVersion\":\"2\",\"m_Curve\":[{\"serializedVersion\":\"3\",\"time\":0.0,\"value\":2.2706568241119386,\"inSlope\":-7.500085353851318,\"outSlope\":-7.500085353851318,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.3333333432674408,\"outWeight\":0.20650266110897065},{\"serializedVersion\":\"3\",\"time\":0.38507816195487978,\"value\":-0.0064108967781066898,\"inSlope\":-2.7670974731445314,\"outSlope\":-2.7670974731445314,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.28388944268226626,\"outWeight\":0.30659767985343935},{\"serializedVersion\":\"3\",\"time\":0.6767024993896484,\"value\":-7.021658420562744,\"inSlope\":-27.286888122558595,\"outSlope\":-27.286888122558595,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.10391546785831452,\"outWeight\":0.12503522634506226},{\"serializedVersion\":\"3\",\"time\":0.9998173117637634,\"value\":-14.818100929260254,\"inSlope\":0.0,\"outSlope\":0.0,\"tangentMode\":0,\"weightedMode\":0,\"inWeight\":0.0,\"outWeight\":0.0}],\"m_PreInfinity\":2,\"m_PostInfinity\":2,\"m_RotationOrder\":4}}");

		[Range(0f, 30f)]
		public float DaytimeEnemiesProbabilityRange = 5f;

		public bool LevelIncludesSnowFootprints = false;

		[HideInInspector]
		public string serializedRandomWeatherTypes;

		[HideInInspector]
		public string serializedDungeonFlowTypes;

		[HideInInspector]
		public string serializedSpawnableScrap;

		[HideInInspector]
		public string serializedEnemies;

		[HideInInspector]
		public string serializedOutsideEnemies;

		[HideInInspector]
		public string serializedDaytimeEnemies;

		[HideInInspector]
		public string serializedSpawnableMapObjects;

		[HideInInspector]
		public string serializedSpawnableOutsideObjects;

		private void OnValidate()
		{
			RequiredBundles = RequiredBundles.RemoveNonAlphanumeric(1);
			IncompatibleBundles = IncompatibleBundles.RemoveNonAlphanumeric(1);
			MoonName = MoonName.RemoveNonAlphanumeric(1);
			OrbitPrefabName = OrbitPrefabName.RemoveNonAlphanumeric(1);
			RiskLevel = RiskLevel.RemoveNonAlphanumeric();
			RouteWord = RouteWord.RemoveNonAlphanumeric(2);
			BoughtComment = BoughtComment.RemoveNonAlphanumeric();
			LevelAmbienceClips = LevelAmbienceClips.RemoveNonAlphanumeric(1);
			TimeToArrive = Mathf.Clamp(TimeToArrive, 0f, 16f);
			DaySpeedMultiplier = Mathf.Clamp(DaySpeedMultiplier, 0.1f, 5f);
			RoutePrice = Mathf.Clamp(RoutePrice, 0, int.MaxValue);
			FactorySizeMultiplier = Mathf.Clamp(FactorySizeMultiplier, 1f, 5f);
			FireExitsAmountOverwrite = Mathf.Clamp(FireExitsAmountOverwrite, 0, 20);
			MinScrap = Mathf.Clamp(MinScrap, 0, MaxScrap);
			MaxScrap = Mathf.Clamp(MaxScrap, MinScrap, 100);
			MaxEnemyPowerCount = Mathf.Clamp(MaxEnemyPowerCount, 0, 30);
			MaxOutsideEnemyPowerCount = Mathf.Clamp(MaxOutsideEnemyPowerCount, 0, 30);
			MaxDaytimeEnemyPowerCount = Mathf.Clamp(MaxDaytimeEnemyPowerCount, 0, 30);
			SpawnProbabilityRange = Mathf.Clamp(SpawnProbabilityRange, 0f, 30f);
			DaytimeEnemiesProbabilityRange = Mathf.Clamp(DaytimeEnemiesProbabilityRange, 0f, 30f);
			for (int i = 0; i < _SpawnableScrap.Length; i++)
			{
				_SpawnableScrap[i].ObjectName = _SpawnableScrap[i].ObjectName.RemoveNonAlphanumeric(1);
			}
			for (int j = 0; j < _Enemies.Length; j++)
			{
				_Enemies[j].EnemyName = _Enemies[j].EnemyName.RemoveNonAlphanumeric(1);
			}
			for (int k = 0; k < _SpawnableMapObjects.Length; k++)
			{
				_SpawnableMapObjects[k].ObjectName = _SpawnableMapObjects[k].ObjectName.RemoveNonAlphanumeric(1);
			}
			for (int l = 0; l < _SpawnableOutsideObjects.Length; l++)
			{
				_SpawnableOutsideObjects[l].ObjectName = _SpawnableOutsideObjects[l].ObjectName.RemoveNonAlphanumeric(1);
			}
			for (int m = 0; m < _OutsideEnemies.Length; m++)
			{
				_OutsideEnemies[m].EnemyName = _OutsideEnemies[m].EnemyName.RemoveNonAlphanumeric(1);
			}
			for (int n = 0; n < _DaytimeEnemies.Length; n++)
			{
				_DaytimeEnemies[n].EnemyName = _DaytimeEnemies[n].EnemyName.RemoveNonAlphanumeric(1);
			}
			serializedRandomWeatherTypes = string.Join(";", _RandomWeatherTypes.Select((RandomWeatherPair p) => $"{(int)p.Weather},{p.WeatherVariable1},{p.WeatherVariable2}"));
			serializedDungeonFlowTypes = string.Join(";", _DungeonFlowTypes.Select((DungeonFlowPair p) => $"{p.ID},{p.Rarity}"));
			serializedSpawnableScrap = string.Join(";", _SpawnableScrap.Select((SpawnableScrapPair p) => $"{p.ObjectName},{p.SpawnWeight}"));
			serializedEnemies = string.Join(";", _Enemies.Select((SpawnableEnemiesPair p) => $"{p.EnemyName},{p.SpawnWeight}"));
			serializedOutsideEnemies = string.Join(";", _OutsideEnemies.Select((SpawnableEnemiesPair p) => $"{p.EnemyName},{p.SpawnWeight}"));
			serializedDaytimeEnemies = string.Join(";", _DaytimeEnemies.Select((SpawnableEnemiesPair p) => $"{p.EnemyName},{p.SpawnWeight}"));
			serializedSpawnableMapObjects = string.Join(";", _SpawnableMapObjects.Select((SpawnableMapObjectPair p) => $"{p.ObjectName}|{p.SpawnFacingAwayFromWall}|{CurveContainer.SerializeCurve(p.SpawnRate)}"));
			serializedSpawnableOutsideObjects = string.Join(";", _SpawnableOutsideObjects.Select((SpawnableOutsideObjectPair p) => p.ObjectName + "|" + CurveContainer.SerializeCurve(p.SpawnRate)));
		}

		public RandomWeatherPair[] RandomWeatherTypes()
		{
			return (from s in serializedRandomWeatherTypes.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 3
				select new RandomWeatherPair((LevelWeatherType)int.Parse(split[0]), int.Parse(split[1]), int.Parse(split[2]))).ToArray();
		}

		public DungeonFlowPair[] DungeonFlowTypes()
		{
			return (from s in serializedDungeonFlowTypes.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new DungeonFlowPair(int.Parse(split[0]), int.Parse(split[1]))).ToArray();
		}

		public SpawnableScrapPair[] SpawnableScrap()
		{
			return (from s in serializedSpawnableScrap.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new SpawnableScrapPair(split[0], int.Parse(split[1]))).ToArray();
		}

		public SpawnableEnemiesPair[] Enemies()
		{
			return (from s in serializedEnemies.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new SpawnableEnemiesPair(split[0], int.Parse(split[1]))).ToArray();
		}

		public SpawnableEnemiesPair[] OutsideEnemies()
		{
			return (from s in serializedOutsideEnemies.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new SpawnableEnemiesPair(split[0], int.Parse(split[1]))).ToArray();
		}

		public SpawnableEnemiesPair[] DaytimeEnemies()
		{
			return (from s in serializedDaytimeEnemies.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new SpawnableEnemiesPair(split[0], int.Parse(split[1]))).ToArray();
		}

		public SpawnableMapObjectPair[] SpawnableMapObjects()
		{
			return (from s in serializedSpawnableMapObjects.Split(new char[1] { ';' })
				select s.Split(new char[1] { '|' }) into split
				where split.Length == 3
				select new SpawnableMapObjectPair(split[0], bool.Parse(split[1]), CurveContainer.DeserializeCurve(split[2]))).ToArray();
		}

		public SpawnableOutsideObjectPair[] SpawnableOutsideObjects()
		{
			return (from s in serializedSpawnableOutsideObjects.Split(new char[1] { ';' })
				select s.Split(new char[1] { '|' }) into split
				where split.Length == 2
				select new SpawnableOutsideObjectPair(split[0], CurveContainer.DeserializeCurve(split[1]))).ToArray();
		}
	}
	[CreateAssetMenu(fileName = "New Scrap", menuName = "LethalSDK/Scrap")]
	public class Scrap : ScriptableObject
	{
		public string[] RequiredBundles;

		public string[] IncompatibleBundles;

		[Header("Base")]
		public string itemName = string.Empty;

		public int minValue = 0;

		public int maxValue = 0;

		public bool twoHanded = false;

		public bool twoHandedAnimation = false;

		public bool requiresBattery = false;

		public bool isConductiveMetal = false;

		public int weight = 0;

		public GameObject prefab;

		[Header("Sounds")]
		public string grabSFX = string.Empty;

		public string dropSFX = string.Empty;

		[Header("Offsets")]
		public float verticalOffset = 0f;

		public Vector3 restingRotation = Vector3.zero;

		public Vector3 positionOffset = Vector3.zero;

		public Vector3 rotationOffset = Vector3.zero;

		[Header("Variants")]
		public Mesh[] meshVariants = (Mesh[])(object)new Mesh[0];

		public Material[] materialVariants = (Material[])(object)new Material[0];

		[Header("Spawn rate")]
		public bool useGlobalSpawnWeight = true;

		[Range(0f, 100f)]
		public int globalSpawnWeight = 10;

		[SerializeField]
		private ScrapSpawnChancePerScene[] _perPlanetSpawnWeight = new ScrapSpawnChancePerScene[8]
		{
			new ScrapSpawnChancePerScene("41 Experimentation", 10),
			new ScrapSpawnChancePerScene("220 Assurance", 10),
			new ScrapSpawnChancePerScene("56 Vow", 10),
			new ScrapSpawnChancePerScene("21 Offense", 10),
			new ScrapSpawnChancePerScene("61 March", 10),
			new ScrapSpawnChancePerScene("85 Rend", 10),
			new ScrapSpawnChancePerScene("7 Dine", 10),
			new ScrapSpawnChancePerScene("8 Titan", 10)
		};

		[HideInInspector]
		public string serializedData;

		private void OnValidate()
		{
			RequiredBundles = RequiredBundles.RemoveNonAlphanumeric(1);
			IncompatibleBundles = IncompatibleBundles.RemoveNonAlphanumeric(1);
			itemName = itemName.RemoveNonAlphanumeric(1);
			grabSFX = grabSFX.RemoveNonAlphanumeric(1);
			dropSFX = dropSFX.RemoveNonAlphanumeric(1);
			for (int i = 0; i < _perPlanetSpawnWeight.Length; i++)
			{
				_perPlanetSpawnWeight[i].SceneName = _perPlanetSpawnWeight[i].SceneName.RemoveNonAlphanumeric(1);
			}
			serializedData = string.Join(";", _perPlanetSpawnWeight.Select((ScrapSpawnChancePerScene p) => $"{p.SceneName},{p.SpawnWeight}"));
		}

		public ScrapSpawnChancePerScene[] perPlanetSpawnWeight()
		{
			return (from s in serializedData.Split(new char[1] { ';' })
				select s.Split(new char[1] { ',' }) into split
				where split.Length == 2
				select new ScrapSpawnChancePerScene(split[0], int.Parse(split[1]))).ToArray();
		}
	}
}
namespace LethalSDK.Utils
{
	public static class AssetGatherDialog
	{
		public static Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();

		public static Dictionary<string, (AudioMixer, AudioMixerGroup[])> audioMixers = new Dictionary<string, (AudioMixer, AudioMixerGroup[])>();

		public static Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();
	}
	[Serializable]
	public class SerializableVersion
	{
		public int Major = 1;

		public int Minor = 0;

		public int Build = 0;

		public int Revision = 0;

		public SerializableVersion(int major, int minor, int build, int revision)
		{
			Major = major;
			Minor = minor;
			Build = build;
			Revision = revision;
		}

		public Version ToVersion()
		{
			return new Version(Major, Minor, Build, Revision);
		}

		public override string ToString()
		{
			return $"{Major}.{Minor}.{Build}.{Revision}";
		}
	}
	[Serializable]
	public class CurveContainer
	{
		public AnimationCurve curve;

		public static string SerializeCurve(AnimationCurve curve)
		{
			CurveContainer curveContainer = new CurveContainer
			{
				curve = curve
			};
			return JsonUtility.ToJson((object)curveContainer);
		}

		public static AnimationCurve DeserializeCurve(string json)
		{
			CurveContainer curveContainer = JsonUtility.FromJson<CurveContainer>(json);
			return curveContainer.curve;
		}
	}
	[Serializable]
	public struct StringIntPair
	{
		public string _string;

		public int _int;

		public StringIntPair(string _string, int _int)
		{
			this._string = _string.RemoveNonAlphanumeric(1);
			this._int = Mathf.Clamp(_int, 0, 100);
		}
	}
	[Serializable]
	public struct StringStringPair
	{
		public string _string1;

		public string _string2;

		public StringStringPair(string _string1, string _string2)
		{
			this._string1 = _string1.RemoveNonAlphanumeric(1);
			this._string2 = _string2.RemoveNonAlphanumeric(1);
		}
	}
	[Serializable]
	public struct IntIntPair
	{
		public int _int1;

		public int _int2;

		public IntIntPair(int _int1, int _int2)
		{
			this._int1 = _int1;
			this._int2 = _int2;
		}
	}
	[Serializable]
	public struct DungeonFlowPair
	{
		public int ID;

		[Range(0f, 300f)]
		public int Rarity;

		public DungeonFlowPair(int id, int rarity)
		{
			ID = id;
			Rarity = Mathf.Clamp(rarity, 0, 300);
		}
	}
	[Serializable]
	public struct SpawnableScrapPair
	{
		public string ObjectName;

		[Range(0f, 100f)]
		public int SpawnWeight;

		public SpawnableScrapPair(string objectName, int spawnWeight)
		{
			ObjectName = objectName.RemoveNonAlphanumeric(1);
			SpawnWeight = Mathf.Clamp(spawnWeight, 0, 100);
		}
	}
	[Serializable]
	public struct SpawnableMapObjectPair
	{
		public string ObjectName;

		public bool SpawnFacingAwayFromWall;

		public AnimationCurve SpawnRate;

		public SpawnableMapObjectPair(string objectName, bool spawnFacingAwayFromWall, AnimationCurve spawnRate)
		{
			ObjectName = objectName.RemoveNonAlphanumeric(1);
			SpawnFacingAwayFromWall = spawnFacingAwayFromWall;
			SpawnRate = spawnRate;
		}
	}
	[Serializable]
	public struct SpawnableOutsideObjectPair
	{
		public string ObjectName;

		public AnimationCurve SpawnRate;

		public SpawnableOutsideObjectPair(string objectName, AnimationCurve spawnRate)
		{
			ObjectName = objectName.RemoveNonAlphanumeric(1);
			SpawnRate = spawnRate;
		}
	}
	[Serializable]
	public struct SpawnableEnemiesPair
	{
		public string EnemyName;

		[Range(0f, 100f)]
		public int SpawnWeight;

		public SpawnableEnemiesPair(string enemyName, int spawnWeight)
		{
			EnemyName = enemyName.RemoveNonAlphanumeric(1);
			SpawnWeight = Mathf.Clamp(spawnWeight, 0, 100);
		}
	}
	[Serializable]
	public struct ScrapSpawnChancePerScene
	{
		public string SceneName;

		[Range(0f, 100f)]
		public int SpawnWeight;

		public ScrapSpawnChancePerScene(string sceneName, int spawnWeight)
		{
			SceneName = sceneName.RemoveNonAlphanumeric(1);
			SpawnWeight = Mathf.Clamp(spawnWeight, 0, 100);
		}
	}
	[Serializable]
	public struct ScrapInfoPair
	{
		public string ScrapPath;

		public Scrap Scrap;

		public ScrapInfoPair(string scrapPath, Scrap scrap)
		{
			ScrapPath = scrapPath.RemoveNonAlphanumeric(4);
			Scrap = scrap;
		}
	}
	[Serializable]
	public struct AudioClipInfoPair
	{
		public string AudioClipName;

		[HideInInspector]
		public string AudioClipPath;

		[SerializeField]
		public AudioClip AudioClip;

		public AudioClipInfoPair(string audioClipName, string audioClipPath)
		{
			AudioClipName = audioClipName.RemoveNonAlphanumeric(1);
			AudioClipPath = audioClipPath.RemoveNonAlphanumeric(4);
			AudioClip = null;
		}
	}
	[Serializable]
	public struct PlanetPrefabInfoPair
	{
		public string PlanetPrefabName;

		[HideInInspector]
		public string PlanetPrefabPath;

		[SerializeField]
		public GameObject PlanetPrefab;

		public PlanetPrefabInfoPair(string planetPrefabName, string planetPrefabPath)
		{
			PlanetPrefabName = planetPrefabName.RemoveNonAlphanumeric(1);
			PlanetPrefabPath = planetPrefabPath.RemoveNonAlphanumeric(4);
			PlanetPrefab = null;
		}
	}
	[Serializable]
	public struct PrefabInfoPair
	{
		public string PrefabName;

		[HideInInspector]
		public string PrefabPath;

		[SerializeField]
		public GameObject Prefab;

		public PrefabInfoPair(string prefabName, string prefabPath)
		{
			PrefabName = prefabName.RemoveNonAlphanumeric(1);
			PrefabPath = prefabPath.RemoveNonAlphanumeric(4);
			Prefab = null;
		}
	}
	[Serializable]
	public struct RandomWeatherPair
	{
		public LevelWeatherType Weather;

		[Tooltip("Thunder Frequency, Flooding speed or minimum initial enemies in eclipses")]
		public int WeatherVariable1;

		[Tooltip("Flooding offset when Weather is Flooded")]
		public int WeatherVariable2;

		public RandomWeatherPair(LevelWeatherType weather, int weatherVariable1, int weatherVariable2)
		{
			Weather = weather;
			WeatherVariable1 = weatherVariable1;
			WeatherVariable2 = weatherVariable2;
		}
	}
	public enum LevelWeatherType
	{
		None = -1,
		DustClouds,
		Rainy,
		Stormy,
		Foggy,
		Flooded,
		Eclipsed
	}
	public class SpawnPrefab
	{
		private static SpawnPrefab _instance;

		public GameObject waterSurface;

		public static SpawnPrefab Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new SpawnPrefab();
				}
				return _instance;
			}
		}
	}
	public static class TypeExtensions
	{
		public enum removeType
		{
			Normal,
			Serializable,
			Keyword,
			Path,
			SerializablePath
		}

		public static readonly Dictionary<removeType, string> regexes = new Dictionary<removeType, string>
		{
			{
				removeType.Normal,
				"[^a-zA-Z0-9 ,.!?_-]"
			},
			{
				removeType.Serializable,
				"[^a-zA-Z0-9 .!_-]"
			},
			{
				removeType.Keyword,
				"[^a-zA-Z0-9._-]"
			},
			{
				removeType.Path,
				"[^a-zA-Z0-9 ,.!_/-]"
			},
			{
				removeType.SerializablePath,
				"[^a-zA-Z0-9 .!_/-]"
			}
		};

		public static string RemoveNonAlphanumeric(this string input)
		{
			if (input != null)
			{
				return Regex.Replace(input, regexes[removeType.Normal], string.Empty);
			}
			return string.Empty;
		}

		public static string[] RemoveNonAlphanumeric(this string[] input)
		{
			if (input != null)
			{
				for (int i = 0; i < input.Length; i++)
				{
					input[i] = Regex.Replace(input[i], regexes[removeType.Normal], string.Empty);
				}
				return input;
			}
			return new string[0];
		}

		public static string RemoveNonAlphanumeric(this string input, removeType removeType = removeType.Normal)
		{
			if (input != null)
			{
				return Regex.Replace(input, regexes[removeType], string.Empty);
			}
			return string.Empty;
		}

		public static string[] RemoveNonAlphanumeric(this string[] input, removeType removeType = removeType.Normal)
		{
			if (input != null)
			{
				for (int i = 0; i < input.Length; i++)
				{
					input[i] = Regex.Replace(input[i], regexes[removeType], string.Empty);
				}
				return input;
			}
			return new string[0];
		}

		public static string RemoveNonAlphanumeric(this string input, int removeType = 0)
		{
			if (input != null)
			{
				return Regex.Replace(input, regexes[(removeType)removeType], string.Empty);
			}
			return string.Empty;
		}

		public static string[] RemoveNonAlphanumeric(this string[] input, int removeType = 0)
		{
			if (input != null)
			{
				for (int i = 0; i < input.Length; i++)
				{
					input[i] = Regex.Replace(input[i], regexes[(removeType)removeType], string.Empty);
				}
				return input;
			}
			return new string[0];
		}
	}
}
namespace LethalSDK.Editor
{
	internal class CopyrightsWindow : EditorWindow
	{
		private Vector2 scrollPosition;

		private readonly Dictionary<string, string> assetAuthorList = new Dictionary<string, string>
		{
			{ "Drop Ship assets, Sun cycle animations, ScrapItem sprite, ScavengerSuit Textures/Arms Mesh and MonitorWall mesh", "Zeekerss" },
			{ "SDK Scripts, Sun Texture, CrossButton Sprite (Inspired of vanilla), OldSeaPort planet prefab texture", "HolographicWings" },
			{ "Old Sea Port asset package", "VIVID Arts" },
			{ "Survival Game Tools asset package", "cookiepopworks.com" }
		};

		[MenuItem("LethalSDK/Copyrights", false, 999)]
		public static void ShowWindow()
		{
			EditorWindow.GetWindow<CopyrightsWindow>("Copyrights");
		}

		private void OnGUI()
		{
			//IL_0018: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("List of Copyrights", EditorStyles.boldLabel, Array.Empty<GUILayoutOption>());
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			EditorGUILayout.Space(5f);
			foreach (KeyValuePair<string, string> assetAuthor in assetAuthorList)
			{
				GUILayout.Label("Asset: " + assetAuthor.Key + " - By: " + assetAuthor.Value, EditorStyles.wordWrappedLabel, Array.Empty<GUILayoutOption>());
				EditorGUILayout.Space(2f);
			}
			EditorGUILayout.Space(5f);
			GUILayout.Label("This SDK do not embed any Vanilla script.", Array.Empty<GUILayoutOption>());
			GUILayout.EndScrollView();
		}
	}
	public class EditorChecker : Editor
	{
		public override void OnInspectorGUI()
		{
			((Editor)this).DrawDefaultInspector();
		}
	}
	[CustomEditor(typeof(ModManifest))]
	public class ModManifestEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			ModManifest modManifest = (ModManifest)(object)((Editor)this).target;
			if (modManifest.serializedVersion == "0.0.0.0")
			{
				EditorGUILayout.HelpBox("Please define a version to your mod and don't forget to increment it at each update.", (MessageType)2);
			}
			if (modManifest.modName == null || modManifest.modName.Length == 0)
			{
				EditorGUILayout.HelpBox("Your mod need a name.", (MessageType)3);
			}
			IEnumerable<string> enumerable = from e in modManifest.scraps.Where((Scrap e) => (Object)(object)e != (Object)null).ToList()
				group e by e.itemName into g
				where g.Count() > 1
				select g.Key;
			if (enumerable.Any())
			{
				string text = string.Empty;
				foreach (string item in enumerable)
				{
					text = text + item + ",";
				}
				text = text.Remove(text.Length - 1);
				EditorGUILayout.HelpBox("You are trying to register two times or more the same Scraps. Duplicated Scraps are: " + text, (MessageType)2);
			}
			IEnumerable<string> enumerable2 = from e in modManifest.moons.Where((Moon e) => (Object)(object)e != (Object)null).ToList()
				group e by e.MoonName into g
				where g.Count() > 1
				select g.Key;
			if (enumerable2.Any())
			{
				string text2 = string.Empty;
				foreach (string item2 in enumerable2)
				{
					text2 = text2 + item2 + ",";
				}
				text2 = text2.Remove(text2.Length - 1);
				EditorGUILayout.HelpBox("You are trying to register two times or more the same Moons. Duplicated Moons are: " + text2, (MessageType)2);
			}
			string text3 = string.Empty;
			Scrap[] scraps = modManifest.scraps;
			foreach (Scrap scrap in scraps)
			{
				if ((Object)(object)scrap != (Object)null && AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)scrap)) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)modManifest)))
				{
					text3 = text3 + ((Object)scrap).name + ",";
				}
			}
			Moon[] moons = modManifest.moons;
			foreach (Moon moon in moons)
			{
				if ((Object)(object)moon != (Object)null && AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)moon)) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)modManifest)))
				{
					text3 = text3 + ((Object)moon).name + ",";
				}
			}
			if (text3 != null && text3.Length > 0)
			{
				text3 = text3.Remove(text3.Length - 1);
				EditorGUILayout.HelpBox("You try to register a Scrap or a Moon from another mod folder. " + text3, (MessageType)2);
			}
			if ((Object)(object)modManifest.assetBank != (Object)null && AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)modManifest.assetBank)) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)modManifest)))
			{
				EditorGUILayout.HelpBox("You try to register an AssetBank from another mod folder.", (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(AssetBank))]
	public class AssetBankEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			AssetBank assetBank = (AssetBank)(object)((Editor)this).target;
			IEnumerable<string> enumerable = from e in (from e in assetBank.AudioClips()
					where e.AudioClipName != null && e.AudioClipName.Length > 0
					select e).ToList()
				group e by e.AudioClipName into g
				where g.Count() > 1
				select g.Key;
			if (enumerable.Any())
			{
				string text = string.Empty;
				foreach (string item in enumerable)
				{
					text = text + item + ",";
				}
				text = text.Remove(text.Length - 1);
				EditorGUILayout.HelpBox("You are trying to register two times or more the same Audio Clip. Duplicated Clips are: " + text, (MessageType)2);
			}
			IEnumerable<string> enumerable2 = from e in (from e in assetBank.PlanetPrefabs()
					where e.PlanetPrefabName != null && e.PlanetPrefabName.Length > 0
					select e).ToList()
				group e by e.PlanetPrefabName into g
				where g.Count() > 1
				select g.Key;
			if (enumerable2.Any())
			{
				string text2 = string.Empty;
				foreach (string item2 in enumerable2)
				{
					text2 = text2 + item2 + ",";
				}
				text2 = text2.Remove(text2.Length - 1);
				EditorGUILayout.HelpBox("You are trying to register two times or more the same Planet Prefabs. Duplicated Planet Prefabs are: " + text2, (MessageType)2);
			}
			string text3 = string.Empty;
			AudioClipInfoPair[] array = assetBank.AudioClips();
			for (int i = 0; i < array.Length; i++)
			{
				AudioClipInfoPair audioClipInfoPair = array[i];
				if (audioClipInfoPair.AudioClipName != null && audioClipInfoPair.AudioClipName.Length > 0 && AssetModificationProcessor.ExtractBundleNameFromPath(audioClipInfoPair.AudioClipPath) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)assetBank)))
				{
					text3 = text3 + audioClipInfoPair.AudioClipName + ",";
				}
			}
			PlanetPrefabInfoPair[] array2 = assetBank.PlanetPrefabs();
			for (int j = 0; j < array2.Length; j++)
			{
				PlanetPrefabInfoPair planetPrefabInfoPair = array2[j];
				if (planetPrefabInfoPair.PlanetPrefabName != null && planetPrefabInfoPair.PlanetPrefabName.Length > 0 && AssetModificationProcessor.ExtractBundleNameFromPath(planetPrefabInfoPair.PlanetPrefabPath) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)assetBank)))
				{
					text3 = text3 + planetPrefabInfoPair.PlanetPrefabName + ",";
				}
			}
			if (text3 != null && text3.Length > 0)
			{
				text3 = text3.Remove(text3.Length - 1);
				EditorGUILayout.HelpBox("You try to register an Audio Clip or a Planet Prefab from another mod folder. " + text3, (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_DungeonGenerator))]
	public class SI_DungeonGeneratorEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_DungeonGenerator sI_DungeonGenerator = (SI_DungeonGenerator)(object)((Editor)this).target;
			string assetPath = AssetDatabase.GetAssetPath((Object)(object)sI_DungeonGenerator.DungeonRoot);
			if (assetPath != null && assetPath.Length > 0)
			{
				EditorGUILayout.HelpBox("Dungeon Root must be in the scene.", (MessageType)3);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_ScanNode))]
	public class SI_ScanNodeEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_ScanNode sI_ScanNode = (SI_ScanNode)(object)((Editor)this).target;
			if (sI_ScanNode.MinRange > sI_ScanNode.MaxRange)
			{
				EditorGUILayout.HelpBox("Min Range must be smaller than Max Ranger.", (MessageType)3);
			}
			if (sI_ScanNode.CreatureScanID < -1)
			{
				EditorGUILayout.HelpBox("Creature Scan ID can't be less than -1.", (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_AnimatedSun))]
	public class SI_AnimatedSunEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_AnimatedSun sI_AnimatedSun = (SI_AnimatedSun)(object)((Editor)this).target;
			if ((Object)(object)sI_AnimatedSun.directLight == (Object)null || (Object)(object)sI_AnimatedSun.indirectLight == (Object)null)
			{
				EditorGUILayout.HelpBox("A direct and an indirect light must be defined.", (MessageType)2);
			}
			if ((Object)(object)((Component)sI_AnimatedSun.directLight).transform.parent != (Object)(object)((Component)sI_AnimatedSun).transform || (Object)(object)((Component)sI_AnimatedSun.indirectLight).transform.parent != (Object)(object)((Component)sI_AnimatedSun).transform)
			{
				EditorGUILayout.HelpBox("Direct and an indirect light must be a child of the AnimatedSun in the hierarchy.", (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_EntranceTeleport))]
	public class SI_EntranceTeleportEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_EntranceTeleport sI_EntranceTeleport = (SI_EntranceTeleport)(object)((Editor)this).target;
			IEnumerable<int> enumerable = from e in Object.FindObjectsOfType<SI_EntranceTeleport>().ToList()
				group e by e.EntranceID into g
				where g.Count() > 1
				select g.Key;
			if (enumerable.Any())
			{
				string text = string.Empty;
				foreach (int item in enumerable)
				{
					text += $"{item},";
				}
				text = text.Remove(text.Length - 1);
				EditorGUILayout.HelpBox("Two entrances or more have same Entrance ID. Duplicated entrances are: " + text, (MessageType)2);
			}
			if ((Object)(object)sI_EntranceTeleport.EntrancePoint == (Object)null)
			{
				EditorGUILayout.HelpBox("An entrance point must be defined.", (MessageType)3);
			}
			if (sI_EntranceTeleport.AudioReverbPreset < 0)
			{
				EditorGUILayout.HelpBox("Audio Reverb Preset can't be negative.", (MessageType)3);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(Scrap))]
	public class ScrapEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			Scrap scrap = (Scrap)(object)((Editor)this).target;
			if ((Object)(object)scrap.prefab == (Object)null)
			{
				EditorGUILayout.HelpBox("You must add a Prefab to your Scrap.", (MessageType)1);
			}
			else
			{
				if ((Object)(object)scrap.prefab.GetComponent<NetworkObject>() == (Object)null)
				{
					EditorGUILayout.HelpBox("The Prefab must have a NetworkObject.", (MessageType)3);
				}
				if ((Object)(object)scrap.prefab.transform.Find("ScanNode") == (Object)null)
				{
					EditorGUILayout.HelpBox("The Prefab don't have a ScanNode.", (MessageType)2);
				}
				if (AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)scrap.prefab)) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)scrap)))
				{
					EditorGUILayout.HelpBox("The Prefab must come from the same mod folder as your Scrap.", (MessageType)2);
				}
			}
			if (scrap.itemName == null || scrap.itemName.Length == 0)
			{
				EditorGUILayout.HelpBox("Your scrap must have a Name.", (MessageType)3);
			}
			if (!scrap.useGlobalSpawnWeight && !scrap.perPlanetSpawnWeight().Any((ScrapSpawnChancePerScene w) => w.SceneName != null && w.SceneName.Length > 0))
			{
				EditorGUILayout.HelpBox("Your scrap use Per Planet Spawn Weight but no planet are defined.", (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(Moon))]
	public class MoonEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			Moon moon = (Moon)(object)((Editor)this).target;
			if (moon.MoonName == null || moon.MoonName.Length == 0)
			{
				EditorGUILayout.HelpBox("Your moon must have a Name.", (MessageType)3);
			}
			if (moon.PlanetName == null || moon.PlanetName.Length == 0)
			{
				EditorGUILayout.HelpBox("Your moon must have a Planet Name.", (MessageType)3);
			}
			if (moon.RouteWord == null || moon.RouteWord.Length < 3)
			{
				EditorGUILayout.HelpBox("Your moon route word must be at least 3 characters long.", (MessageType)3);
			}
			if ((Object)(object)moon.MainPrefab == (Object)null)
			{
				EditorGUILayout.HelpBox("You must add a Main Prefab to your Scrap.", (MessageType)1);
			}
			else if (AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)moon.MainPrefab)) != AssetModificationProcessor.ExtractBundleNameFromPath(AssetDatabase.GetAssetPath((Object)(object)moon)))
			{
				EditorGUILayout.HelpBox("The Main Prefab must come from the same mod folder as your Moon.", (MessageType)2);
			}
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_DoorLock))]
	public class SI_DoorLockEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_DoorLock sI_DoorLock = (SI_DoorLock)(object)((Editor)this).target;
			EditorGUILayout.HelpBox("DoorLock is not implemented yet.", (MessageType)1);
			base.OnInspectorGUI();
		}
	}
	[CustomEditor(typeof(SI_Ladder))]
	public class SI_LadderEditor : EditorChecker
	{
		public override void OnInspectorGUI()
		{
			SI_Ladder sI_Ladder = (SI_Ladder)(object)((Editor)this).target;
			EditorGUILayout.HelpBox("Ladder is experimental.", (MessageType)1);
			base.OnInspectorGUI();
		}
	}
	internal class OldAssetsRemover
	{
		private static readonly List<string> assetPaths = new List<string>
		{
			"Assets/LethalCompanyAssets", "Assets/Mods/LethalExpansion/Audio", "Assets/Mods/LethalExpansion/AudioMixerController", "Assets/Mods/LethalExpansion/Materials/Default.mat", "Assets/Mods/LethalExpansion/Prefabs/Settings", "Assets/Mods/LethalExpansion/Prefabs/EntranceTeleportA.prefab", "Assets/Mods/LethalExpansion/Prefabs/Prefabs.zip", "Assets/Mods/LethalExpansion/Scenes/ItemPlaceTest", "Assets/Mods/LethalExpansion/Sprites/HandIcon.png", "Assets/Mods/LethalExpansion/Sprites/HandIconPoint.png",
			"Assets/Mods/LethalExpansion/Sprites/HandLadderIcon.png", "Assets/Mods/TemplateMod/Moons/NavMesh-Environment.asset", "Assets/Mods/TemplateMod/Moons/OldSeaPort.asset", "Assets/Mods/TemplateMod/Moons/Sky and Fog Global Volume Profile.asset", "Assets/Mods/TemplateMod/Moons/Sky and Fog Global Volume Profile 1.asset", "Assets/Mods/TemplateMod/AssetBank.asset", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunCompanyLevel.anim", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeB.anim", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeBEclipse.anim", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeBStormy.anim",
			"Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeC.anim", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeCEclipse.anim", "Assets/Mods/LethalExpansion/Animations/Sun/TimeOfDaySunTypeCStormy.anim", "Assets/Mods/LethalExpansion/Skybox", "Assets/Mods/LethalExpansion/Sprites/XButton.png", "Assets/Mods/LethalExpansion/Textures/sunTexture1.png", "Assets/Mods/OldSeaPort/Materials/Maple_bark_1.mat", "Assets/Mods/OldSeaPort/Materials/maple_leaves.mat", "Assets/Mods/TemplateMod/AssetBank.asset", "Assets/Mods/OldSeaPort/EffectExamples/Shared/Scripts",
			"Assets/Mods/OldSeaPort/scenes", "Assets/Mods/OldSeaPort/prefabs/Plane (12).prefab", "Assets/Mods/LethalExpansion/Meshes/labyrinth.fbx"
		};

		[InitializeOnLoadMethod]
		public static void CheckOldAssets()
		{
			foreach (string assetPath in assetPaths)
			{
				if (AssetDatabase.IsValidFolder(assetPath))
				{
					DeleteFolder(assetPath);
				}
				else if ((Object)(object)AssetDatabase.LoadAssetAtPath<GameObject>(assetPath) != (Object)null)
				{
					DeleteAsset(assetPath);
				}
			}
		}

		private static void DeleteFolder(string path)
		{
			if (AssetDatabase.DeleteAsset(path))
			{
				Debug.Log((object)("Deleted folder at: " + path));
			}
			else
			{
				Debug.LogError((object)("Failed to delete folder at: " + path));
			}
		}

		private static void DeleteAsset(string path)
		{
			if (AssetDatabase.DeleteAsset(path))
			{
				Debug.Log((object)("Deleted asset at: " + path));
			}
			else
			{
				Debug.LogError((object)("Failed to delete asset at: " + path));
			}
		}
	}
	public class VersionChecker : Editor
	{
		[InitializeOnLoadMethod]
		public static void CheckVersion()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			UnityWebRequest www = UnityWebRequest.Get("https://raw.githubusercontent.com/HolographicWings/LethalSDK-Unity-Project/main/last.txt");
			UnityWebRequestAsyncOperation operation = www.SendWebRequest();
			CallbackFunction callback = null;
			callback = (CallbackFunction)delegate
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Expected O, but got Unknown
				if (((AsyncOperation)operation).isDone)
				{
					EditorApplication.update = (CallbackFunction)Delegate.Remove((Delegate?)(object)EditorApplication.update, (Delegate?)(object)callback);
					OnRequestComplete(www);
				}
			};
			EditorApplication.update = (CallbackFunction)Delegate.Combine((Delegate?)(object)EditorApplication.update, (Delegate?)(object)callback);
		}

		private static void OnRequestComplete(UnityWebRequest www)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			if ((int)www.result == 2 || (int)www.result == 3)
			{
				Debug.LogError((object)("Error when getting last version number: " + www.error));
			}
			else
			{
				CompareVersions(www.downloadHandler.text);
			}
		}

		private static void CompareVersions(string onlineVersion)
		{
			if (Version.Parse(PlayerSettings.bundleVersion) < Version.Parse(onlineVersion) && EditorUtility.DisplayDialogComplex("Warning", "The SDK is not up to date: " + onlineVersion, "Update", "Ignore", "") == 0)
			{
				Application.OpenURL("https://thunderstore.io/c/lethal-company/p/HolographicWings/LethalSDK/");
			}
		}
	}
	internal class LethalSDKCategory : EditorWindow
	{
		[MenuItem("LethalSDK/Lethal SDK v1.3.0", false, 0)]
		public static void ShowWindow()
		{
		}
	}
	public class Lethal_AssetBundleBuilderWindow : EditorWindow
	{
		private enum compressionOption
		{
			NormalCompression,
			FastCompression,
			Uncompressed
		}

		private static string assetBundleDirectoryKey = "LethalSDK_AssetBundleBuilderWindow_assetBundleDirectory";

		private static string compressionModeKey = "LethalSDK_AssetBundleBuilderWindow_compressionMode";

		private static string _64BitsModeKey = "LethalSDK_AssetBundleBuilderWindow_64BitsMode";

		private string assetBundleDirectory = string.Empty;

		private compressionOption compressionMode = compressionOption.NormalCompression;

		private bool _64BitsMode;

		[MenuItem("LethalSDK/AssetBundle Builder", false, 100)]
		public static void ShowWindow()
		{
			//IL_0017: 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)
			Lethal_AssetBundleBuilderWindow window = EditorWindow.GetWindow<Lethal_AssetBundleBuilderWindow>("AssetBundle Builder");
			((EditorWindow)window).minSize = new Vector2(295f, 133f);
			((EditorWindow)window).maxSize = new Vector2(295f, 133f);
			window.LoadPreferences();
		}

		private void OnGUI()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			GUILayout.Label("Base Settings", EditorStyles.boldLabel, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			EditorGUILayout.LabelField(new GUIContent("Output Path", "The directory where the asset bundles will be saved."), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(84f) });
			assetBundleDirectory = EditorGUILayout.TextField(assetBundleDirectory, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) });
			GUILayout.EndHorizontal();
			EditorGUILayout.Space(5f);
			GUILayout.Label("Options", EditorStyles.boldLabel, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			EditorGUILayout.LabelField(new GUIContent("Compression Mode", "Select the compression option for the asset bundle. Faster the compression is, faster the assets will load and less CPU it will use, but the Bundle will be bigger."), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(145f) });
			compressionMode = (compressionOption)(object)EditorGUILayout.EnumPopup((Enum)compressionMode, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) });
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			EditorGUILayout.LabelField(new GUIContent("64 Bits Asset Bundle (Not recommended)", "Better performances but incompatible with 32 bits computers."), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(270f) });
			_64BitsMode = EditorGUILayout.Toggle(_64BitsMode, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			EditorGUILayout.Space(5f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Build AssetBundles", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) }))
			{
				BuildAssetBundles();
			}
			if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) }))
			{
				ClearPreferences();
			}
			GUILayout.EndHorizontal();
		}

		private void ClearPreferences()
		{
			EditorPrefs.DeleteKey(assetBundleDirectoryKey);
			EditorPrefs.DeleteKey(compressionModeKey);
			EditorPrefs.DeleteKey(_64BitsModeKey);
			LoadPreferences();
		}

		private void BuildAssetBundles()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (!Directory.Exists(assetBundleDirectory))
			{
				Directory.CreateDirectory(assetBundleDirectory);
			}
			BuildAssetBundleOptions val = (BuildAssetBundleOptions)0;
			val = (BuildAssetBundleOptions)(compressionMode switch
			{
				compressionOption.NormalCompression => 0, 
				compressionOption.FastCompression => 256, 
				compressionOption.Uncompressed => 1, 
				_ => 0, 
			});
			BuildTarget val2 = (BuildTarget)(_64BitsMode ? 19 : 5);
			try
			{
				if (assetBundleDirectory != null || assetBundleDirectory.Length != 0)
				{
					AssetBundleManifest val3 = BuildPipeline.BuildAssetBundles(assetBundleDirectory, val, val2);
					if ((Object)(object)val3 != (Object)null)
					{
						Debug.Log((object)"AssetBundles built successfully.");
					}
					else
					{
						Debug.LogError((object)"Cannot build AssetBundles.");
					}
				}
				else
				{
					Debug.LogError((object)"AssetBundles path cannot be blank.");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)ex.Message);
			}
		}

		private void OnLostFocus()
		{
			SavePreferences();
		}

		private void OnDisable()
		{
			SavePreferences();
		}

		private void LoadPreferences()
		{
			assetBundleDirectory = EditorPrefs.GetString(assetBundleDirectoryKey, "Assets/AssetBundles");
			compressionMode = (compressionOption)EditorPrefs.GetInt(compressionModeKey, 0);
			_64BitsMode = EditorPrefs.GetBool(_64BitsModeKey, false);
		}

		private void SavePreferences()
		{
			EditorPrefs.SetString(assetBundleDirectoryKey, assetBundleDirectory);
			EditorPrefs.SetInt(compressionModeKey, (int)compressionMode);
			EditorPrefs.SetBool(_64BitsModeKey, _64BitsMode);
		}
	}
}
namespace LethalSDK.Component
{
	[AddComponentMenu("LethalSDK/DamagePlayer")]
	public class SI_DamagePlayer : MonoBehaviour
	{
		public bool kill = false;

		public bool dontSpawnBody = false;

		public SI_CauseOfDeath causeOfDeath = SI_CauseOfDeath.Gravity;

		public int damages = 25;

		public int numberIterations = 1;

		public int iterationCooldown = 1000;

		public int warmupCooldown = 0;

		public UnityEvent postEvent = new UnityEvent();

		public void Trigger(object player)
		{
			if (kill)
			{
				((MonoBehaviour)this).StartCoroutine(Kill(player));
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(Damage(player));
			}
		}

		public IEnumerator Kill(object player)
		{
			yield return (object)new WaitForSeconds((float)warmupCooldown / 1000f);
			((PlayerControllerB)((player is PlayerControllerB) ? player : null)).KillPlayer(Vector3.zero, !dontSpawnBody, (CauseOfDeath)causeOfDeath, 0);
			postEvent.Invoke();
		}

		public IEnumerator Damage(object player)
		{
			yield return (object)new WaitForSeconds((float)warmupCooldown / 1000f);
			int iteration = 0;
			while (iteration < numberIterations || numberIterations == -1)
			{
				((PlayerControllerB)((player is PlayerControllerB) ? player : null)).DamagePlayer(damages, true, true, (CauseOfDeath)causeOfDeath, 0, false, Vector3.zero);
				postEvent.Invoke();
				iteration++;
				yield return (object)new WaitForSeconds((float)iterationCooldown / 1000f);
			}
		}

		public void StopCounter(object player)
		{
			((MonoBehaviour)this).StopAllCoroutines();
		}
	}
	[AddComponentMenu("LethalSDK/SoundYDistance")]
	public class SI_SoundYDistance : MonoBehaviour
	{
		public AudioSource audioSource;

		public int maxDistance = 50;

		public void Awake()
		{
			if ((Object)(object)audioSource == (Object)null)
			{
				audioSource = ((Component)this).gameObject.GetComponent<AudioSource>();
				if ((Object)(object)audioSource == (Object)null)
				{
					audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
				}
			}
		}

		public void Update()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)StartOfRound.Instance != (Object)null)
			{
				audioSource.volume = 1f - Mathf.Abs(((Component)this).transform.position.y - ((Component)RoundManager.Instance.playersManager.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[((NetworkBehaviour)StartOfRound.Instance).NetworkManager.LocalClientId]].gameplayCamera).transform.position.y) / (float)maxDistance;
			}
		}
	}
	[AddComponentMenu("LethalSDK/AudioOutputInterface")]
	public class SI_AudioOutputInterface : MonoBehaviour
	{
		public AudioSource audioSource;

		public string mixerName = "Diagetic";

		public string mixerGroupName = "Master";

		public void Awake()
		{
			if ((Object)(object)audioSource == (Object)null)
			{
				audioSource = ((Component)this).gameObject.GetComponent<AudioSource>();
				if ((Object)(object)audioSource == (Object)null)
				{
					audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
				}
			}
			if (mixerName != null && mixerName.Length > 0 && mixerGroupName != null && mixerGroupName.Length > 0)
			{
				audioSource.outputAudioMixerGroup = AssetGatherDialog.audioMixers[mixerName].Item2.First((AudioMixerGroup g) => ((Object)g).name == mixerGroupName);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	[AddComponentMenu("LethalSDK/NetworkPrefabInstancier")]
	public class SI_NetworkPrefabInstancier : MonoBehaviour
	{
		public GameObject prefab;

		public GameObject instance;

		public void Awake()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab != (Object)null)
			{
				NetworkObject component = prefab.GetComponent<NetworkObject>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.NetworkManager != (Object)null && component.NetworkManager.IsHost)
				{
					instance = Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, ((Component)this).transform.rotation, ((Component)this).transform.parent);
					instance.GetComponent<NetworkObject>().Spawn(false);
				}
			}
			((Component)this).gameObject.SetActive(false);
		}

		public void OnDestroy()
		{
			if ((Object)(object)instance != (Object)null)
			{
				NetworkObject component = prefab.GetComponent<NetworkObject>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.NetworkManager != (Object)null && component.NetworkManager.IsHost)
				{
					instance.GetComponent<NetworkObject>().Despawn(true);
					Object.Destroy((Object)(object)instance);
				}
			}
		}
	}
	public class ScriptImporter : MonoBehaviour
	{
		public virtual void Awake()
		{
			Object.Destroy((Object)(object)this);
		}
	}
	[AddComponentMenu("LethalSDK/MatchLocalPlayerPosition")]
	public class SI_MatchLocalPlayerPosition : ScriptImporter
	{
		public override void Awake()
		{
			((Component)this).gameObject.AddComponent<MatchLocalPlayerPosition>();
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/AnimatedSun")]
	public class SI_AnimatedSun : ScriptImporter
	{
		public Light indirectLight;

		public Light directLight;

		public override void Awake()
		{
			animatedSun val = ((Component)this).gameObject.AddComponent<animatedSun>();
			val.indirectLight = indirectLight;
			val.directLight = directLight;
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/ScanNode")]
	public class SI_ScanNode : ScriptImporter
	{
		public int MaxRange;

		public int MinRange;

		public bool RequiresLineOfSight;

		public string HeaderText;

		public string SubText;

		public int ScrapValue;

		public int CreatureScanID;

		public NodeType NodeType;

		public override void Awake()
		{
			ScanNodeProperties val = ((Component)this).gameObject.AddComponent<ScanNodeProperties>();
			val.minRange = MinRange;
			val.maxRange = MaxRange;
			val.requiresLineOfSight = RequiresLineOfSight;
			val.headerText = HeaderText;
			val.subText = SubText;
			val.scrapValue = ScrapValue;
			val.creatureScanID = CreatureScanID;
			val.nodeType = (int)NodeType;
			base.Awake();
		}
	}
	public enum NodeType
	{
		Information = 0,
		Danger = 0,
		Ressource = 0
	}
	[AddComponentMenu("LethalSDK/AudioReverbPresets")]
	public class SI_AudioReverbPresets : ScriptImporter
	{
		public GameObject[] presets;

		public override void Awake()
		{
		}

		public void Update()
		{
			int num = 0;
			GameObject[] array = presets;
			foreach (GameObject val in array)
			{
				if ((Object)(object)val.GetComponent<SI_AudioReverbTrigger>() != (Object)null)
				{
					num++;
				}
			}
			if (num != 0)
			{
				return;
			}
			List<AudioReverbTrigger> list = new List<AudioReverbTrigger>();
			GameObject[] array2 = presets;
			foreach (GameObject val2 in array2)
			{
				if ((Object)(object)val2.GetComponent<AudioReverbTrigger>() != (Object)null)
				{
					list.Add(val2.GetComponent<AudioReverbTrigger>());
				}
			}
			AudioReverbPresets val3 = ((Component)this).gameObject.AddComponent<AudioReverbPresets>();
			val3.audioPresets = list.ToArray();
			Object.Destroy((Object)(object)this);
		}
	}
	[AddComponentMenu("LethalSDK/AudioReverbTrigger")]
	public class SI_AudioReverbTrigger : ScriptImporter
	{
		[Header("Reverb Preset")]
		public bool ChangeDryLevel = false;

		[Range(-10000f, 0f)]
		public float DryLevel = 0f;

		public bool ChangeHighFreq = false;

		[Range(-10000f, 0f)]
		public float HighFreq = -270f;

		public bool ChangeLowFreq = false;

		[Range(-10000f, 0f)]
		public float LowFreq = -244f;

		public bool ChangeDecayTime = false;

		[Range(0f, 35f)]
		public float DecayTime = 1.4f;

		public bool ChangeRoom = false;

		[Range(-10000f, 0f)]
		public float Room = -600f;

		[Header("MISC")]
		public bool ElevatorTriggerForProps = false;

		public bool SetInElevatorTrigger = false;

		public bool IsShipRoom = false;

		public bool ToggleLocalFog = false;

		public float FogEnabledAmount = 10f;

		[Header("Weather and effects")]
		public bool SetInsideAtmosphere = false;

		public bool InsideLighting = false;

		public int WeatherEffect = -1;

		public bool EffectEnabled = true;

		public bool DisableAllWeather = false;

		public bool EnableCurrentLevelWeather = true;

		public override void Awake()
		{
			AudioReverbTrigger val = ((Component)this).gameObject.AddComponent<AudioReverbTrigger>();
			ReverbPreset val2 = ScriptableObject.CreateInstance<ReverbPreset>();
			val2.changeDryLevel = ChangeDryLevel;
			val2.dryLevel = DryLevel;
			val2.changeHighFreq = ChangeHighFreq;
			val2.highFreq = HighFreq;
			val2.changeLowFreq = ChangeLowFreq;
			val2.lowFreq = LowFreq;
			val2.changeDecayTime = ChangeDecayTime;
			val2.decayTime = DecayTime;
			val2.changeRoom = ChangeRoom;
			val2.room = Room;
			val.reverbPreset = val2;
			val.usePreset = -1;
			val.audioChanges = (switchToAudio[])(object)new switchToAudio[0];
			val.elevatorTriggerForProps = ElevatorTriggerForProps;
			val.setInElevatorTrigger = SetInElevatorTrigger;
			val.isShipRoom = IsShipRoom;
			val.toggleLocalFog = ToggleLocalFog;
			val.fogEnabledAmount = FogEnabledAmount;
			val.setInsideAtmosphere = SetInsideAtmosphere;
			val.insideLighting = InsideLighting;
			val.weatherEffect = WeatherEffect;
			val.effectEnabled = EffectEnabled;
			val.disableAllWeather = DisableAllWeather;
			val.enableCurrentLevelWeather = EnableCurrentLevelWeather;
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/DungeonGenerator")]
	public class SI_DungeonGenerator : ScriptImporter
	{
		public GameObject DungeonRoot;

		public override void Awake()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)this).tag != "DungeonGenerator")
			{
				((Component)this).tag = "DungeonGenerator";
			}
			RuntimeDungeon val = ((Component)this).gameObject.AddComponent<RuntimeDungeon>();
			val.Generator.DungeonFlow = RoundManager.Instance.dungeonFlowTypes[0];
			val.Generator.LengthMultiplier = 0.8f;
			val.Generator.PauseBetweenRooms = 0.2f;
			val.GenerateOnStart = false;
			if ((Object)(object)DungeonRoot != (Object)null)
			{
				_ = DungeonRoot.scene;
				if (false)
				{
					DungeonRoot = new GameObject();
					((Object)DungeonRoot).name = "DungeonRoot";
					DungeonRoot.transform.position = new Vector3(0f, -200f, 0f);
				}
			}
			val.Root = DungeonRoot;
			val.Generator.DungeonFlow = RoundManager.Instance.dungeonFlowTypes[0];
			UnityNavMeshAdapter val2 = ((Component)this).gameObject.AddComponent<UnityNavMeshAdapter>();
			val2.BakeMode = (RuntimeNavMeshBakeMode)3;
			val2.LayerMask = LayerMask.op_Implicit(35072);
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/EntranceTeleport")]
	public class SI_EntranceTeleport : ScriptImporter
	{
		public int EntranceID = 0;

		public Transform EntrancePoint;

		public int AudioReverbPreset = -1;

		public AudioClip[] DoorAudios = (AudioClip[])(object)new AudioClip[0];

		public override void Awake()
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
			val.outputAudioMixerGroup = AssetGatherDialog.audioMixers["Diagetic"].Item2.First((AudioMixerGroup g) => ((Object)g).name == "Master");
			val.playOnAwake = false;
			val.spatialBlend = 1f;
			EntranceTeleport entranceTeleport = ((Component)this).gameObject.AddComponent<EntranceTeleport>();
			entranceTeleport.isEntranceToBuilding = true;
			entranceTeleport.entrancePoint = EntrancePoint;
			entranceTeleport.entranceId = EntranceID;
			entranceTeleport.audioReverbPreset = AudioReverbPreset;
			entranceTeleport.entrancePointAudio = val;
			entranceTeleport.doorAudios = DoorAudios;
			InteractTrigger val2 = ((Component)this).gameObject.AddComponent<InteractTrigger>();
			val2.hoverIcon = (AssetGatherDialog.sprites.ContainsKey("HandIcon") ? AssetGatherDialog.sprites["HandIcon"] : AssetGatherDialog.sprites.First().Value);
			val2.hoverTip = "Enter : [LMB]";
			val2.disabledHoverTip = string.Empty;
			val2.holdTip = string.Empty;
			val2.animationString = string.Empty;
			val2.interactable = true;
			val2.oneHandedItemAllowed = true;
			val2.twoHandedItemAllowed = true;
			val2.holdInteraction = true;
			val2.timeToHold = 1.5f;
			val2.timeToHoldSpeedMultiplier = 1f;
			val2.holdingInteractEvent = new InteractEventFloat();
			val2.onInteract = new InteractEvent();
			val2.onInteractEarly = new InteractEvent();
			val2.onStopInteract = new InteractEvent();
			val2.onCancelAnimation = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)val2.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				entranceTeleport.TeleportPlayer();
			});
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/DoorLock")]
	public class SI_DoorLock : ScriptImporter
	{
		public override void Awake()
		{
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/WaterSurface")]
	public class SI_WaterSurface : ScriptImporter
	{
		private GameObject obj;

		public int soundMaxDistance = 50;

		public override void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			obj = Object.Instantiate<GameObject>(SpawnPrefab.Instance.waterSurface);
			SceneManager.MoveGameObjectToScene(obj, ((Component)this).gameObject.scene);
			obj.transform.parent = ((Component)this).transform;
			obj.transform.localPosition = Vector3.zero;
			Transform val = obj.transform.Find("Water");
			((Component)val).GetComponent<MeshFilter>().sharedMesh = ((Component)this).GetComponent<MeshFilter>().sharedMesh;
			val.position = ((Component)this).transform.position;
			val.rotation = ((Component)this).transform.rotation;
			val.localScale = ((Component)this).transform.localScale;
			SI_SoundYDistance sI_SoundYDistance = ((Component)val).gameObject.AddComponent<SI_SoundYDistance>();
			sI_SoundYDistance.audioSource = ((Component)obj.transform.Find("WaterAudio")).GetComponent<AudioSource>();
			sI_SoundYDistance.maxDistance = soundMaxDistance;
			obj.SetActive(true);
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/Ladder")]
	public class SI_Ladder : ScriptImporter
	{
		public Transform BottomPosition;

		public Transform TopPosition;

		public Transform HorizontalPosition;

		public Transform PlayerNodePosition;

		public bool UseRaycastToGetTopPosition = false;

		public override void Awake()
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			InteractTrigger val = ((Component)this).gameObject.AddComponent<InteractTrigger>();
			val.hoverIcon = (AssetGatherDialog.sprites.ContainsKey("HandLadderIcon") ? AssetGatherDialog.sprites["HandLadderIcon"] : AssetGatherDialog.sprites.First().Value);
			val.hoverTip = "Climb : [LMB]";
			val.disabledHoverTip = string.Empty;
			val.holdTip = string.Empty;
			val.animationString = string.Empty;
			val.specialCharacterAnimation = true;
			val.animationWaitTime = 0.5f;
			val.animationString = "SA_PullLever";
			val.isLadder = true;
			val.lockPlayerPosition = true;
			val.playerPositionNode = BottomPosition;
			val.bottomOfLadderPosition = BottomPosition;
			val.bottomOfLadderPosition = BottomPosition;
			val.topOfLadderPosition = TopPosition;
			val.ladderHorizontalPosition = HorizontalPosition;
			val.ladderPlayerPositionNode = PlayerNodePosition;
			val.useRaycastToGetTopPosition = UseRaycastToGetTopPosition;
			val.holdingInteractEvent = new InteractEventFloat();
			val.onCancelAnimation = new InteractEvent();
			val.onInteract = new InteractEvent();
			val.onInteractEarly = new InteractEvent();
			val.onStopInteract = new InteractEvent();
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/ItemDropship")]
	public class SI_ItemDropship : ScriptImporter
	{
		public Animator ShipAnimator;

		public Transform[] ItemSpawnPositions;

		public GameObject OpenTriggerObject;

		public GameObject KillTriggerObject;

		public AudioClip ShipThrusterCloseSound;

		public AudioClip ShipLandSound;

		public AudioClip ShipOpenDoorsSound;

		public override void Awake()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			ItemDropship ItemDropship = ((Component)this).gameObject.AddComponent<ItemDropship>();
			ItemDropship.shipAnimator = ShipAnimator;
			ItemDropship.itemSpawnPositions = ItemSpawnPositions;
			PlayAudioAnimationEvent val = ((Component)this).gameObject.AddComponent<PlayAudioAnimationEvent>();
			val.audioToPlay = ((Component)this).GetComponent<AudioSource>();
			val.audioClip = ShipLandSound;
			val.audioClip2 = ShipOpenDoorsSound;
			InteractTrigger val2 = OpenTriggerObject.AddComponent<InteractTrigger>();
			val2.hoverIcon = (AssetGatherDialog.sprites.ContainsKey("HandIcon") ? AssetGatherDialog.sprites["HandIcon"] : AssetGatherDialog.sprites.First().Value);
			val2.hoverTip = "Open : [LMB]";
			val2.disabledHoverTip = string.Empty;
			val2.holdTip = string.Empty;
			val2.animationString = string.Empty;
			val2.twoHandedItemAllowed = true;
			val2.onInteract = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)val2.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				ItemDropship.TryOpeningShip();
			});
			ItemDropship.triggerScript = val2;
			if ((Object)(object)((Component)ItemDropship).transform.Find("Music") != (Object)null)
			{
				((Component)((Component)ItemDropship).transform.Find("Music")).gameObject.AddComponent<OccludeAudio>();
				if ((Object)(object)((Component)this).transform.Find("ThrusterContainer/Thruster") != (Object)null)
				{
					facePlayerOnAxis val3 = ((Component)((Component)this).transform.Find("ThrusterContainer/Thruster")).gameObject.AddComponent<facePlayerOnAxis>();
					val3.turnAxis = ((Component)this).transform.Find("ThrusterContainer/flameAxis");
				}
			}
			KillLocalPlayer KillLocalPlayerScript = KillTriggerObject.AddComponent<KillLocalPlayer>();
			InteractTrigger val4 = KillTriggerObject.AddComponent<InteractTrigger>();
			val4.hoverTip = string.Empty;
			val4.disabledHoverTip = string.Empty;
			val4.holdTip = string.Empty;
			val4.animationString = string.Empty;
			val4.touchTrigger = true;
			val4.triggerOnce = true;
			val4.onInteract = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)val4.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate(PlayerControllerB player)
			{
				KillLocalPlayerScript.KillPlayer(player);
			});
			base.Awake();
		}
	}
	[AddComponentMenu("LethalSDK/InteractTrigger")]
	public class SI_InteractTrigger : ScriptImporter
	{
		[Header("Aesthetics")]
		public string hoverIcon = "HandIcon";

		public string hoverTip = "Interact";

		public string disabledHoverIcon = string.Empty;

		public string disabledHoverTip = string.Empty;

		[Header("Interaction")]
		public bool interactable = true;

		public bool oneHandedItemAllowed = true;

		public bool twoHandedItemAllowed = false;

		public bool holdInteraction = false;

		public float timeToHold = 0.5f;

		public float timeToHoldSpeedMultiplier = 1f;

		public string holdTip = string.Empty;

		public UnityEvent<float> holdingInteractEvent = new UnityEvent<float>();

		public bool touchTrigger = false;

		public bool triggerOnce = false;

		[Header("Misc")]
		public bool interactCooldown = true;

		public float cooldownTime = 1f;

		public bool disableTriggerMesh = true;

		public bool RandomChanceTrigger = false;

		public int randomChancePercentage = 0;

		[Header("Events")]
		public UnityEvent<object> onInteract = new UnityEvent<object>();

		public UnityEvent<object> onInteractEarly = new UnityEvent<object>();

		public UnityEvent<object> onStopInteract = new UnityEvent<object>();

		public UnityEvent<object> onCancelAnimation = new UnityEvent<object>();

		[Header("Special Animation")]
		public bool specialCharacterAnimation = false;

		public bool stopAnimationManually = false;

		public string stopAnimationString = "SA_stopAnimation";

		public bool hidePlayerItem = false;

		public bool isPlayingSpecialAnimation = false;

		public float animationWaitTime = 2f;

		public string animationString = string.Empty;

		public bool lockPlayerPosition = false;

		public Transform playerPositionNode;

		[Header("Ladders")]
		public bool isLadder = false;

		public Transform topOfLadderPosition;

		public bool useRaycastToGetTopPosition = false;

		public Transform bottomOfLadderPosition;

		public Transform ladderHorizontalPosition;

		public Transform ladderPlayerPositionNode;

		public override void Awake()
		{
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			InteractTrigger val = ((Component)this).gameObject.AddComponent<InteractTrigger>();
			if (hoverIcon != null && hoverIcon.Length > 0)
			{
				val.hoverIcon = null;
			}
			else
			{
				val.hoverIcon = (AssetGatherDialog.sprites.ContainsKey(hoverIcon) ? AssetGatherDialog.sprites[hoverIcon] : AssetGatherDialog.sprites.First().Value);
			}
			val.hoverTip = hoverTip;
			if (disabledHoverIcon != null && disabledHoverIcon.Length > 0)
			{
				val.disabledHoverIcon = null;
			}
			else
			{
				val.disabledHoverIcon = (AssetGatherDialog.sprites.ContainsKey(disabledHoverIcon) ? AssetGatherDia

BepInEx/plugins/LateCompanyV1.0.7.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("LateCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dd1c760480cb012e5275a3b7e6464b2b2dffb1d0")]
[assembly: AssemblyProduct("LateCompany")]
[assembly: AssemblyTitle("LateCompany")]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LateCompany
{
	public static class PluginInfo
	{
		public const string GUID = "twig.latecompany";

		public const string PrintName = "Late Company";

		public const string Version = "1.0.7";
	}
	[BepInPlugin("twig.latecompany", "Late Company", "1.0.7")]
	internal class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> configLateJoinOrbitOnly;

		public static bool OnlyLateJoinInOrbit = false;

		public static bool LobbyJoinable = true;

		public void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			configLateJoinOrbitOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Late join orbit only", true, "Don't allow joining while the ship is not in orbit.");
			OnlyLateJoinInOrbit = configLateJoinOrbitOnly.Value;
			Harmony val = new Harmony("twig.latecompany");
			val.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.Log((LogLevel)16, (object)"Late Company loaded!");
		}

		public static void SetLobbyJoinable(bool joinable)
		{
			LobbyJoinable = joinable;
			GameNetworkManager.Instance.SetLobbyJoinable(joinable);
			QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>();
			if (Object.op_Implicit((Object)(object)val))
			{
				val.inviteFriendsTextAlpha.alpha = (joinable ? 1f : 0.2f);
			}
		}
	}
}
namespace LateCompany.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")]
	[HarmonyWrapSafe]
	internal static class LeaveLobbyAtGameStart_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
	[HarmonyWrapSafe]
	internal static class ConnectionApproval_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(ConnectionApprovalRequest request, ConnectionApprovalResponse response)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (request.ClientNetworkId != NetworkManager.Singleton.LocalClientId && response.Reason.Contains("Game has already started") && Plugin.LobbyJoinable)
			{
				response.Reason = "";
				response.CreatePlayerObject = false;
				response.Approved = true;
				response.Pending = false;
			}
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "DisableInviteFriendsButton")]
	internal static class DisableInviteFriendsButton_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")]
	internal static class InviteFriendsButton_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			if (Plugin.LobbyJoinable)
			{
				GameNetworkManager.Instance.InviteFriendsUI();
			}
			return false;
		}
	}
	internal class RpcEnum : NetworkBehaviour
	{
		public static int None => 0;

		public static int Client => 2;

		public static int Server => 1;
	}
	internal static class WeatherSync
	{
		public static bool DoOverride = false;

		public static LevelWeatherType CurrentWeather = (LevelWeatherType)(-1);
	}
	[HarmonyPatch(typeof(RoundManager), "__rpc_handler_1193916134")]
	[HarmonyWrapSafe]
	internal static class __rpc_handler_1193916134_Patch
	{
		public static FieldInfo RPCExecStage = typeof(NetworkBehaviour).GetField("__rpc_exec_stage", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPrefix]
		private static bool Prefix(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if ((Object)(object)networkManager != (Object)null && networkManager.IsListening)
			{
				try
				{
					int num = default(int);
					ByteUnpacker.ReadValueBitPacked(reader, ref num);
					int num2 = default(int);
					ByteUnpacker.ReadValueBitPacked(reader, ref num2);
					int num3 = default(int);
					ByteUnpacker.ReadValueBitPacked(reader, ref num3);
					WeatherSync.CurrentWeather = (LevelWeatherType)num3;
					WeatherSync.DoOverride = true;
					RPCExecStage.SetValue(target, RpcEnum.Client);
					((RoundManager)((target is RoundManager) ? target : null)).GenerateNewLevelClientRpc(num, num2);
					RPCExecStage.SetValue(target, RpcEnum.None);
				}
				catch
				{
					WeatherSync.DoOverride = false;
					((FastBufferReader)(ref reader)).Seek(0);
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SetToCurrentLevelWeather")]
	internal static class SetToCurrentLevelWeather_Patch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (WeatherSync.DoOverride)
			{
				RoundManager.Instance.currentLevel.currentWeather = WeatherSync.CurrentWeather;
				WeatherSync.DoOverride = false;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")]
	[HarmonyWrapSafe]
	internal static class OnPlayerConnectedClientRpc_Patch
	{
		public static MethodInfo BeginSendClientRpc = typeof(RoundManager).GetMethod("__beginSendClientRpc", BindingFlags.Instance | BindingFlags.NonPublic);

		public static MethodInfo EndSendClientRpc = typeof(RoundManager).GetMethod("__endSendClientRpc", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPostfix]
		private static void Postfix(ulong clientId, int connectedPlayers, ulong[] connectedPlayerIdsOrdered, int assignedPlayerObjectId, int serverMoneyAmount, int levelID, int profitQuota, int timeUntilDeadline, int quotaFulfilled, int randomSeed)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0106: Expected I4, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			PlayerControllerB val = instance.allPlayerScripts[assignedPlayerObjectId];
			if (instance.connectedPlayersAmount + 1 >= instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: false);
			}
			val.DisablePlayerModel(instance.allPlayerObjects[assignedPlayerObjectId], true, true);
			if (((NetworkBehaviour)instance).IsServer && !instance.inShipPhase)
			{
				RoundManager instance2 = RoundManager.Instance;
				ClientRpcParams val2 = default(ClientRpcParams);
				val2.Send = new ClientRpcSendParams
				{
					TargetClientIds = new List<ulong> { clientId }
				};
				ClientRpcParams val3 = val2;
				FastBufferWriter val4 = (FastBufferWriter)BeginSendClientRpc.Invoke(instance2, new object[3] { 1193916134u, val3, 0 });
				BytePacker.WriteValueBitPacked(val4, StartOfRound.Instance.randomMapSeed);
				BytePacker.WriteValueBitPacked(val4, StartOfRound.Instance.currentLevelID);
				BytePacker.WriteValueBitPacked(val4, (int)instance2.currentLevel.currentWeather);
				EndSendClientRpc.Invoke(instance2, new object[4] { val4, 1193916134u, val3, 0 });
				FastBufferWriter val5 = (FastBufferWriter)BeginSendClientRpc.Invoke(instance2, new object[3] { 2729232387u, val3, 0 });
				EndSendClientRpc.Invoke(instance2, new object[4] { val5, 2729232387u, val3, 0 });
			}
			instance.livingPlayers = instance.connectedPlayersAmount + 1;
			for (int i = 0; i < instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val6 = instance.allPlayerScripts[i];
				if (val6.isPlayerControlled && val6.isPlayerDead)
				{
					instance.livingPlayers--;
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
	[HarmonyWrapSafe]
	internal static class OnPlayerDC_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (StartOfRound.Instance.inShipPhase || (!Plugin.OnlyLateJoinInOrbit && StartOfRound.Instance.shipHasLanded))
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")]
	internal static class SetShipReadyToLand_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (Plugin.OnlyLateJoinInOrbit && StartOfRound.Instance.connectedPlayersAmount + 1 < StartOfRound.Instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "StartGame")]
	internal static class StartGame_Patch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			Plugin.SetLobbyJoinable(joinable: false);
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
	internal static class OnShipLandedMiscEvents_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (!Plugin.OnlyLateJoinInOrbit && StartOfRound.Instance.connectedPlayersAmount + 1 < StartOfRound.Instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
	internal static class ShipLeave_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Plugin.SetLobbyJoinable(joinable: false);
		}
	}
}

BepInEx/plugins/KillBind.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using KillBindNS;
using LethalCompanyInputUtils.Api;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KillBind")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KillBind")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6dd5353c-1d70-400e-8a33-a26482141e1d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace KillBind.Binds
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class KillBindPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void onPressKill(PlayerControllerB __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (BasePlugin.ModEnabled.Value && BasePlugin.InputActionInstance.ExplodeKey.triggered && !__instance.isPlayerDead && !__instance.isTypingChat && !((Behaviour)HUDManager.Instance.typingIndicator).enabled && !Object.FindObjectOfType<Terminal>().terminalInUse && !__instance.inTerminalMenu)
			{
				__instance.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1);
			}
		}
	}
}
namespace KillBindNS
{
	public class KillBind : LcInputActions
	{
		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction ExplodeKey { get; set; }
	}
	[BepInPlugin("Confusified.KillBind", "Kill Bind", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BasePlugin : BaseUnityPlugin
	{
		private const string modGUID = "Confusified.KillBind";

		private const string modName = "Kill Bind";

		private const string modVersion = "1.0.0";

		private readonly Harmony _harmony = new Harmony("Confusified.KillBind");

		public ConfigFile Configuration = new ConfigFile(Utility.CombinePaths(new string[2]
		{
			Paths.ConfigPath + "\\Confusified\\",
			"Confusified.KillBind".Substring(12) + ".cfg"
		}), false);

		public static ConfigEntry<bool> ModEnabled;

		internal static KillBind InputActionInstance = new KillBind();

		private void Awake()
		{
			SetModConfig();
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Kill Bind 1.0.0 has loaded");
		}

		private void SetModConfig()
		{
			ModEnabled = Configuration.Bind<bool>("Mod Settings", "Enabled", true, "Toggle the mod");
		}
	}
}

BepInEx/plugins/Killbind/KillBind.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using KillBindNS;
using LethalCompanyInputUtils.Api;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("KillBind")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KillBind")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6dd5353c-1d70-400e-8a33-a26482141e1d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace KillBind.Binds
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class KillBindPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void onPressKill(PlayerControllerB __instance)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (BasePlugin.ModEnabled.Value && BasePlugin.InputActionInstance.ExplodeKey.triggered && !__instance.isPlayerDead && !__instance.isTypingChat && !((Behaviour)HUDManager.Instance.typingIndicator).enabled && !Object.FindObjectOfType<Terminal>().terminalInUse && !__instance.inTerminalMenu && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				if (BasePlugin.DeathCause.Value > Enum.GetValues(typeof(CauseOfDeath)).Length)
				{
					BasePlugin.DeathCause.Value = 0;
				}
				int num = 0;
				num = (BasePlugin.BlowHeadOff.Value ? 1 : 0);
				__instance.KillPlayer(Vector3.zero, true, (CauseOfDeath)BasePlugin.DeathCause.Value, num);
			}
		}
	}
}
namespace KillBindNS
{
	public class KillBind : LcInputActions
	{
		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction ExplodeKey { get; set; }
	}
	[BepInPlugin("Confusified.KillBind", "Kill Bind", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BasePlugin : BaseUnityPlugin
	{
		private const string modGUID = "Confusified.KillBind";

		private const string modName = "Kill Bind";

		private const string modVersion = "1.1.0";

		private readonly Harmony _harmony = new Harmony("Confusified.KillBind");

		public ConfigFile Configuration = new ConfigFile(Utility.CombinePaths(new string[2]
		{
			Paths.ConfigPath + "\\Confusified\\",
			"Confusified.KillBind".Substring(12) + ".cfg"
		}), false);

		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<int> DeathCause;

		public static ConfigEntry<bool> BlowHeadOff;

		internal static KillBind InputActionInstance = new KillBind();

		private void Awake()
		{
			SetModConfig();
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Kill Bind 1.1.0 has loaded");
		}

		private void SetModConfig()
		{
			ModEnabled = Configuration.Bind<bool>("Global Settings", "Enabled", true, "Toggle the mod");
			DeathCause = Configuration.Bind<int>("Mod Settings", "DeathType", 0, "Decide what cause of death you will have when pressing your kill bind.\nThere are currently 13 death causes in the game:\n(0) Unknown (Default)\n(1) Bludgeoning\n(2) Gravity\n(3) Blast\n(4) Strangulation\n(5) Suffocation\n(6) Mauling\n(7) Gunshots\n(8) Crushing\n(9) Drowning\n(10) Abandoned\n(11) Electrocution\n(12) Kicking\n\nDeath types (1)Bludgeoning, (6)Mauling and (7)Gunshots will cover the body with blood.");
			BlowHeadOff = Configuration.Bind<bool>("Mod Settings", "BlowHeadOff", true, "Blow off your head when pressing your kill bind");
		}
	}
}

BepInEx/plugins/DiscountAlert.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("DiscountAlert")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0.0")]
[assembly: AssemblyProduct("DiscountAlert")]
[assembly: AssemblyTitle("DiscountAlert")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(StartMatchLever))]
public class StartMatchLever_Patches
{
	public static string priceUpColor = "#990000";

	public static string priceDownColor = "#008000";

	public static bool playerAlerted;

	[HarmonyPatch("PlayLeverPullEffectsClientRpc")]
	[HarmonyPostfix]
	public static void PlayLeverPullEffectsClientRpcPatch()
	{
		if (!StartOfRound.Instance.inShipPhase)
		{
			return;
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < HUDManager.Instance.terminalScript.buyableItemsList.Length; i++)
		{
			if (HUDManager.Instance.terminalScript.itemSalesPercentages[i] != 100)
			{
				if (HUDManager.Instance.terminalScript.itemSalesPercentages[i] < 0)
				{
					stringBuilder.Append("\n<color=" + priceUpColor + ">* " + HUDManager.Instance.terminalScript.buyableItemsList[i].itemName + $" ${(float)HUDManager.Instance.terminalScript.buyableItemsList[i].creditsWorth * (1f - (float)HUDManager.Instance.terminalScript.itemSalesPercentages[i] / 100f)} " + $"({Math.Abs(HUDManager.Instance.terminalScript.itemSalesPercentages[i])}% UP!)</color>");
				}
				else if (HUDManager.Instance.terminalScript.itemSalesPercentages[i] > 0)
				{
					stringBuilder.Append("\n<color=" + priceDownColor + ">* " + HUDManager.Instance.terminalScript.buyableItemsList[i].itemName + $" ${(float)HUDManager.Instance.terminalScript.buyableItemsList[i].creditsWorth * (float)HUDManager.Instance.terminalScript.itemSalesPercentages[i] / 100f} " + $"({100 - HUDManager.Instance.terminalScript.itemSalesPercentages[i]}% OFF!)</color>");
				}
			}
		}
		if (stringBuilder.ToString() == "" || stringBuilder == null)
		{
			stringBuilder.Append("None :( \nCheck back tomorrow!");
		}
		HUDManager.Instance.DisplayTip("Today's discounts", stringBuilder.ToString(), false, false, "LC_Tip1");
	}
}
namespace DiscountAlert
{
	[BepInPlugin("discount.alert", "DiscountAlert", "1.0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "discount.alert";

		private const string modName = "DiscountAlert";

		private const string modVersion = "1.0.0.0";

		private readonly Harmony harmony = new Harmony("discount.alert");

		private static Plugin? Instance;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin discount.alert is loaded!");
			harmony.PatchAll();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/plugins/backrooms/Backrooms.dll

Decompiled 8 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.AI.Navigation;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
	}
}
[RequireComponent(typeof(SphereCollider))]
public class KillBox : MonoBehaviour
{
	private void OnTriggerEnter(Collider other)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
		if ((Object)(object)component != (Object)null)
		{
			component.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0);
		}
	}
}
public class LightFlickerEffect : MonoBehaviour
{
	[Tooltip("External light to flicker; you can leave this null if you attach script to a light")]
	public Light light;

	[Tooltip("Minimum random light intensity")]
	public float minIntensity;

	[Tooltip("Maximum random light intensity")]
	public float maxIntensity = 1f;

	[Tooltip("How much to smooth out the randomness; lower values = sparks, higher = lantern")]
	[Range(1f, 50f)]
	public int smoothing = 5;

	private Queue<float> smoothQueue;

	private float lastSum;

	public void Reset()
	{
		smoothQueue.Clear();
		lastSum = 0f;
	}

	private void Start()
	{
		smoothQueue = new Queue<float>(smoothing);
		if ((Object)(object)light == (Object)null)
		{
			light = ((Component)this).GetComponent<Light>();
		}
	}

	private void Update()
	{
		if (!((Object)(object)light == (Object)null))
		{
			while (smoothQueue.Count >= smoothing)
			{
				lastSum -= smoothQueue.Dequeue();
			}
			float num = Random.Range(minIntensity, maxIntensity);
			smoothQueue.Enqueue(num);
			lastSum += num;
			light.intensity = lastSum / (float)smoothQueue.Count;
		}
	}
}
public class LookAtPlayer : MonoBehaviour
{
	private void Update()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).gameObject.transform.LookAt(((Component)GameNetworkManager.Instance.localPlayerController).transform.position + Vector3.up);
	}
}
public class SpawnPosition : MonoBehaviour
{
	private void Start()
	{
	}

	private void Update()
	{
	}
}
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		MonoScriptData result = default(MonoScriptData);
		result.FilePathsData = new byte[506]
		{
			0, 0, 0, 1, 0, 0, 0, 42, 92, 65,
			115, 115, 101, 116, 115, 92, 66, 97, 99, 107,
			114, 111, 111, 109, 115, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 65, 114, 101, 89, 111, 117,
			87, 97, 116, 99, 104, 101, 100, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 38, 92, 65,
			115, 115, 101, 116, 115, 92, 66, 97, 99, 107,
			114, 111, 111, 109, 115, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 66, 97, 99, 107, 114, 111,
			111, 109, 115, 46, 99, 115, 0, 0, 0, 1,
			0, 0, 0, 33, 92, 65, 115, 115, 101, 116,
			115, 92, 66, 97, 99, 107, 114, 111, 111, 109,
			115, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			69, 120, 105, 116, 46, 99, 115, 0, 0, 0,
			1, 0, 0, 0, 33, 92, 65, 115, 115, 101,
			116, 115, 92, 66, 97, 99, 107, 114, 111, 111,
			109, 115, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 72, 111, 111, 107, 46, 99, 115, 0, 0,
			0, 1, 0, 0, 0, 36, 92, 65, 115, 115,
			101, 116, 115, 92, 66, 97, 99, 107, 114, 111,
			111, 109, 115, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 75, 105, 108, 108, 66, 111, 120, 46,
			99, 115, 0, 0, 0, 1, 0, 0, 0, 47,
			92, 65, 115, 115, 101, 116, 115, 92, 66, 97,
			99, 107, 114, 111, 111, 109, 115, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 76, 105, 103, 104,
			116, 70, 108, 105, 99, 107, 101, 114, 69, 102,
			102, 101, 99, 116, 46, 99, 115, 0, 0, 0,
			1, 0, 0, 0, 35, 92, 65, 115, 115, 101,
			116, 115, 92, 66, 97, 99, 107, 114, 111, 111,
			109, 115, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 76, 111, 97, 100, 101, 114, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 41, 92, 65,
			115, 115, 101, 116, 115, 92, 66, 97, 99, 107,
			114, 111, 111, 109, 115, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 76, 111, 111, 107, 65, 116,
			80, 108, 97, 121, 101, 114, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 36, 92, 65, 115,
			115, 101, 116, 115, 92, 66, 97, 99, 107, 114,
			111, 111, 109, 115, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 83, 107, 105, 98, 105, 100, 105,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			35, 92, 65, 115, 115, 101, 116, 115, 92, 66,
			97, 99, 107, 114, 111, 111, 109, 115, 92, 83,
			99, 114, 105, 112, 116, 115, 92, 83, 109, 105,
			108, 101, 114, 46, 99, 115, 0, 0, 0, 1,
			0, 0, 0, 42, 92, 65, 115, 115, 101, 116,
			115, 92, 66, 97, 99, 107, 114, 111, 111, 109,
			115, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			83, 112, 97, 119, 110, 80, 111, 115, 105, 116,
			105, 111, 110, 46, 99, 115
		};
		result.TypesData = new byte[233]
		{
			0, 0, 0, 0, 25, 66, 97, 99, 107, 114,
			111, 111, 109, 115, 124, 66, 97, 99, 107, 114,
			111, 111, 109, 115, 72, 101, 108, 112, 101, 114,
			0, 0, 0, 0, 19, 66, 97, 99, 107, 114,
			111, 111, 109, 115, 124, 66, 97, 99, 107, 114,
			111, 111, 109, 115, 0, 0, 0, 0, 14, 66,
			97, 99, 107, 114, 111, 111, 109, 115, 124, 69,
			120, 105, 116, 0, 0, 0, 0, 14, 66, 97,
			99, 107, 114, 111, 111, 109, 115, 124, 72, 111,
			111, 107, 0, 0, 0, 0, 8, 124, 75, 105,
			108, 108, 66, 111, 120, 0, 0, 0, 0, 19,
			124, 76, 105, 103, 104, 116, 70, 108, 105, 99,
			107, 101, 114, 69, 102, 102, 101, 99, 116, 0,
			0, 0, 0, 16, 66, 97, 99, 107, 114, 111,
			111, 109, 115, 124, 76, 111, 97, 100, 101, 114,
			0, 0, 0, 0, 13, 124, 76, 111, 111, 107,
			65, 116, 80, 108, 97, 121, 101, 114, 0, 0,
			0, 0, 20, 66, 97, 99, 107, 114, 111, 111,
			109, 115, 124, 83, 111, 117, 110, 100, 80, 97,
			116, 99, 104, 0, 0, 0, 0, 16, 66, 97,
			99, 107, 114, 111, 111, 109, 115, 124, 83, 109,
			105, 108, 101, 114, 0, 0, 0, 0, 14, 124,
			83, 112, 97, 119, 110, 80, 111, 115, 105, 116,
			105, 111, 110
		};
		result.TotalFiles = 11;
		result.TotalTypes = 11;
		result.IsEditorOnly = false;
		return result;
	}
}
namespace Backrooms;

public class BackroomsHelper : MonoBehaviour
{
	public bool HasBeenInTheBackrooms;

	private void Start()
	{
	}

	private void Update()
	{
	}
}
public class Backrooms : NetworkBehaviour
{
	public static Backrooms Instance;

	public GameObject Floor;

	public GameObject Wall;

	public GameObject Ceiling;

	public GameObject LightlessCeiling;

	public GameObject Pillar;

	public GameObject Room;

	public static float Offset = -500f;

	private int Width = 30;

	private int Height = 30;

	public List<Vector2> PossibleSpawnPoint;

	public List<PlayerControllerB> playerInBackrooms;

	public NetworkVariable<float> SharedOdds = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	private float initialValue;

	public DungeonFlow Flow;

	public GameObject Child;

	public override void OnNetworkSpawn()
	{
		if (((NetworkBehaviour)this).IsServer)
		{
			initialValue = Loader.TeleportationOdds.Value;
			SharedOdds.Value = initialValue;
			((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback += NetworkManager_OnClientConnectedCallback;
			return;
		}
		if (SharedOdds.Value != initialValue)
		{
			Debug.LogWarning((object)($"NetworkVariable was {SharedOdds.Value} upon being spawned" + $" when it should have been {initialValue}"));
		}
		else
		{
			Debug.Log((object)$"NetworkVariable is {SharedOdds.Value} when spawned.");
		}
		NetworkVariable<float> sharedOdds = SharedOdds;
		sharedOdds.OnValueChanged = (OnValueChangedDelegate<float>)(object)Delegate.Combine((Delegate?)(object)sharedOdds.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<float>(OnSomeValueChanged));
	}

	private void NetworkManager_OnClientConnectedCallback(ulong obj)
	{
		StartChangingNetworkVariable();
	}

	private void OnSomeValueChanged(float previous, float current)
	{
		Debug.Log((object)$"Detected NetworkVariable Change: Previous: {previous} | Current: {current}");
	}

	private void StartChangingNetworkVariable()
	{
		((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback -= NetworkManager_OnClientConnectedCallback;
	}

	private void Awake()
	{
		PossibleSpawnPoint = new List<Vector2>();
		playerInBackrooms = new List<PlayerControllerB>();
	}

	private void Start()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
	}

	private IEnumerator Teleport()
	{
		yield return (object)new WaitForSeconds(10f);
		for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
		{
			if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled)
			{
				TeleportToBackroomsClientRpc(i);
			}
		}
	}

	public void ServerGenerate()
	{
		int seed = Random.Range(0, 1000000);
		GenerateClientRpc(seed);
	}

	public void ServerClean()
	{
		Smiler[] array = Object.FindObjectsOfType<Smiler>();
		for (int i = 0; i < array.Length; i++)
		{
			((Component)array[i]).GetComponent<NetworkObject>().Despawn(true);
		}
		playerInBackrooms.Clear();
		CleanBackroomsClientRpc();
	}

	[ClientRpc]
	public void CleanBackroomsClientRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2180494496u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2180494496u, val, (RpcDelivery)0);
		}
		if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
		{
			return;
		}
		foreach (Transform item in ((Component)this).transform)
		{
			Object.Destroy((Object)(object)((Component)item).gameObject);
		}
		PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
		for (int i = 0; i < allPlayerScripts.Length; i++)
		{
			((Component)allPlayerScripts[i]).GetComponent<BackroomsHelper>().HasBeenInTheBackrooms = false;
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void TeleportToBackroomsServerRpc(int client)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2541916904u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, client);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2541916904u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				TeleportToBackroomsClientRpc(client);
			}
		}
	}

	[ClientRpc]
	public void TeleportToBackroomsClientRpc(int client)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//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_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3078584200u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, client);
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3078584200u, val, (RpcDelivery)0);
		}
		if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
		{
			PlayerControllerB val3 = StartOfRound.Instance.allPlayerScripts[client];
			Random.InitState(client);
			Vector2 val4 = PossibleSpawnPoint[Random.Range(0, PossibleSpawnPoint.Count)];
			val3.TeleportPlayer(new Vector3(val4.x, Offset, val4.y), false, 0f, false, true);
			val3.isInsideFactory = true;
			val3.ResetFallGravity();
			((Component)val3).GetComponent<BackroomsHelper>().HasBeenInTheBackrooms = true;
			if (((NetworkBehaviour)this).IsServer)
			{
				playerInBackrooms.Add(val3);
			}
		}
	}

	[ClientRpc]
	public void TeleportOutOfBackroomsClientRpc(int client)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1623403188u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, client);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1623403188u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				PlayerControllerB obj = StartOfRound.Instance.allPlayerScripts[client];
				obj.TeleportPlayer(StartOfRound.Instance.playerSpawnPositions[0].position, false, 0f, false, true);
				obj.isInsideFactory = false;
			}
		}
	}

	[ClientRpc]
	public void GenerateClientRpc(int seed)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0134: 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_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: 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_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_0373: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0545: Unknown result type (might be due to invalid IL or missing references)
		//IL_054a: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0559: Unknown result type (might be due to invalid IL or missing references)
		//IL_0560: Unknown result type (might be due to invalid IL or missing references)
		//IL_0565: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_049a: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(890432861u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, seed);
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 890432861u, val, (RpcDelivery)0);
		}
		if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
		{
			return;
		}
		PossibleSpawnPoint.Clear();
		playerInBackrooms.Clear();
		Random random = new Random(seed);
		Debug.Log((object)"Generate floor and ceiling");
		for (int i = -Width / 2; i < Width / 2; i++)
		{
			for (int j = -Height / 2; j < Height / 2; j++)
			{
				Object.Instantiate<GameObject>(Floor, new Vector3((float)(i * 6), Offset, (float)(j * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
				if (random.Next(100) < 85)
				{
					Object.Instantiate<GameObject>(LightlessCeiling, new Vector3((float)(i * 6), Offset + 5f, (float)(j * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
				}
				else
				{
					Object.Instantiate<GameObject>(Ceiling, new Vector3((float)(i * 6), Offset + 5f, (float)(j * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
				}
			}
		}
		Debug.Log((object)"Generate walls");
		for (int k = -Width / 2; k < Width / 2; k++)
		{
			Object.Instantiate<GameObject>(Wall, new Vector3((float)(-Width / 2 * 6 - 3), Offset, (float)(k * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
			if (k != 0)
			{
				Object.Instantiate<GameObject>(Wall, new Vector3((float)(Width / 2 * 6 - 3), Offset, (float)(k * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
				continue;
			}
			Debug.Log((object)"Generate room");
			Object.Instantiate<GameObject>(Room, new Vector3((float)(Width / 2 * 6 - 3), Offset, (float)(k * 6)), Quaternion.Euler(0f, 90f, 0f), ((Component)this).transform);
		}
		Debug.Log((object)"Generate walls 2");
		for (int l = -Width / 2; l < Width / 2; l++)
		{
			Object.Instantiate<GameObject>(Wall, new Vector3((float)(l * 6), Offset, (float)(-Height / 2 * 6 - 3)), Quaternion.Euler(-90f, 90f, 0f), ((Component)this).transform);
			Object.Instantiate<GameObject>(Wall, new Vector3((float)(l * 6), Offset, (float)(Height / 2 * 6 - 3)), Quaternion.Euler(-90f, 90f, 0f), ((Component)this).transform);
		}
		Debug.Log((object)"Generate inside 2");
		for (int m = -Width / 2; m < Width / 2; m++)
		{
			for (int n = -Height / 2; n < Height / 2; n++)
			{
				if (m == 0 && n == 0)
				{
					continue;
				}
				int num = random.Next(20);
				if (num < 15)
				{
					if (random.Next(10) < 5)
					{
						Object.Instantiate<GameObject>(Wall, new Vector3((float)(m * 6 - 3), Offset, (float)(n * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
					}
					else
					{
						Object.Instantiate<GameObject>(Wall, new Vector3((float)(m * 6), Offset, (float)(n * 6 - 3)), Quaternion.Euler(-90f, 90f, 0f), ((Component)this).transform);
					}
				}
				else if (num == 16)
				{
					Object.Instantiate<GameObject>(Pillar, new Vector3((float)(m * 6), Offset, (float)(n * 6)), Quaternion.Euler(-90f, 0f, 0f), ((Component)this).transform);
				}
				else
				{
					PossibleSpawnPoint.Add(new Vector2((float)(m * 6), (float)(n * 6)));
				}
			}
		}
		if (((NetworkBehaviour)this).IsServer)
		{
			((Component)this).GetComponent<NavMeshSurface>().BuildNavMesh();
			GameObject val3 = Loader.AssetBundle.LoadAsset<GameObject>("assets/backrooms/smile.prefab");
			for (int num2 = 0; num2 < Loader.NumberOfSmilers.Value; num2++)
			{
				Vector2 val4 = PossibleSpawnPoint[Random.Range(0, PossibleSpawnPoint.Count)];
				Object.Instantiate<GameObject>(val3, new Vector3(val4.x, Offset, val4.y), Quaternion.identity, ((Component)this).transform).GetComponent<NetworkObject>().Spawn(false);
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void TeleportOutOfBackroomsServerRpc(ulong clientId)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3409688981u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3409688981u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				TeleportOutOfBackroomsClientRpc((int)clientId);
			}
		}
	}

	protected override void __initializeVariables()
	{
		if (SharedOdds == null)
		{
			throw new Exception("Backrooms.SharedOdds cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)SharedOdds).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SharedOdds, "SharedOdds");
		base.NetworkVariableFields.Add((NetworkVariableBase)(object)SharedOdds);
		((NetworkBehaviour)this).__initializeVariables();
	}

	[RuntimeInitializeOnLoadMethod]
	internal static void InitializeRPCS_Backrooms()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		NetworkManager.__rpc_func_table.Add(2180494496u, new RpcReceiveHandler(__rpc_handler_2180494496));
		NetworkManager.__rpc_func_table.Add(2541916904u, new RpcReceiveHandler(__rpc_handler_2541916904));
		NetworkManager.__rpc_func_table.Add(3078584200u, new RpcReceiveHandler(__rpc_handler_3078584200));
		NetworkManager.__rpc_func_table.Add(1623403188u, new RpcReceiveHandler(__rpc_handler_1623403188));
		NetworkManager.__rpc_func_table.Add(890432861u, new RpcReceiveHandler(__rpc_handler_890432861));
		NetworkManager.__rpc_func_table.Add(3409688981u, new RpcReceiveHandler(__rpc_handler_3409688981));
	}

	private static void __rpc_handler_2180494496(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((Backrooms)(object)target).CleanBackroomsClientRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2541916904(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int client = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref client);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((Backrooms)(object)target).TeleportToBackroomsServerRpc(client);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3078584200(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int client = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref client);
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((Backrooms)(object)target).TeleportToBackroomsClientRpc(client);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_1623403188(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int client = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref client);
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((Backrooms)(object)target).TeleportOutOfBackroomsClientRpc(client);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_890432861(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int seed = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref seed);
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((Backrooms)(object)target).GenerateClientRpc(seed);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3409688981(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			ulong clientId = default(ulong);
			ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((Backrooms)(object)target).TeleportOutOfBackroomsServerRpc(clientId);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	protected internal override string __getTypeName()
	{
		return "Backrooms";
	}
}
public class Exit : MonoBehaviour
{
	private void Start()
	{
	}

	private IEnumerator Teleport(ulong playerClientId)
	{
		StartOfRound.Instance.allPlayerScripts[playerClientId].beamOutParticle.Play();
		yield return (object)new WaitForSeconds(3f);
		Backrooms.Instance.TeleportOutOfBackroomsServerRpc(playerClientId);
	}

	private void OnTriggerEnter(Collider other)
	{
		PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
		if ((Object)(object)component != (Object)null)
		{
			((MonoBehaviour)this).StartCoroutine(Teleport(component.playerClientId));
			Backrooms.Instance.TeleportOutOfBackroomsServerRpc(component.playerClientId);
		}
	}
}
public static class Hook
{
	[HarmonyPatch(typeof(KillLocalPlayer), "KillPlayer")]
	[HarmonyPrefix]
	private static bool BeforeKilling(PlayerControllerB playerWhoTriggered)
	{
		if (playerWhoTriggered.isPlayerDead || !playerWhoTriggered.AllowPlayerDeath())
		{
			return true;
		}
		if (((Component)playerWhoTriggered).GetComponent<BackroomsHelper>().HasBeenInTheBackrooms)
		{
			return true;
		}
		Debug.Log((object)$"Killzone {Backrooms.Instance.SharedOdds.Value}");
		if ((float)Random.Range(0, 100) < Backrooms.Instance.SharedOdds.Value)
		{
			Backrooms.Instance.TeleportToBackroomsServerRpc((int)playerWhoTriggered.playerClientId);
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
	[HarmonyPrefix]
	private static bool BeforeDamage(PlayerControllerB __instance)
	{
		if (__instance.isPlayerDead || !__instance.AllowPlayerDeath())
		{
			return true;
		}
		if (((Component)__instance).GetComponent<BackroomsHelper>().HasBeenInTheBackrooms)
		{
			return true;
		}
		Debug.Log((object)$"Damage taken {Backrooms.Instance.SharedOdds.Value}");
		if ((float)Random.Range(0, 100) < Backrooms.Instance.SharedOdds.Value)
		{
			Backrooms.Instance.TeleportToBackroomsServerRpc((int)__instance.playerClientId);
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(PlayerControllerB), "Start")]
	[HarmonyPostfix]
	private static void AddComponents(PlayerControllerB __instance)
	{
		((Component)__instance).gameObject.AddComponent<BackroomsHelper>();
	}

	[HarmonyPatch(typeof(RoundManager), "Start")]
	[HarmonyPostfix]
	private static void SpawnBackrooms(RoundManager __instance)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (((NetworkBehaviour)__instance).IsServer)
		{
			Debug.Log((object)"Spawning backrooms");
			Object.Instantiate<GameObject>(Loader.AssetBundle.LoadAsset<GameObject>("assets/backrooms/backrooms.prefab"), new Vector3(0f, Backrooms.Offset, 0f), Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
		}
	}

	[HarmonyPatch(typeof(RoundManager), "UnloadSceneObjectsEarly")]
	[HarmonyPostfix]
	public static void DeleteBackrooms(RoundManager __instance)
	{
		if (((NetworkBehaviour)__instance).IsServer)
		{
			Backrooms.Instance.ServerClean();
		}
	}

	[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
	[HarmonyPrefix]
	public static void GenerateBackrooms(RoundManager __instance)
	{
		if (((NetworkBehaviour)__instance).IsServer)
		{
			Backrooms.Instance.ServerGenerate();
		}
	}

	[HarmonyPatch(typeof(StartOfRound), "WritePlayerNotes")]
	[HarmonyPostfix]
	public static void BackroomsPlayerNote(StartOfRound __instance)
	{
		for (int i = 0; i < __instance.gameStats.allPlayerStats.Length; i++)
		{
			if (__instance.gameStats.allPlayerStats[i].isActivePlayer && ((Component)__instance.allPlayerScripts[i]).GetComponent<BackroomsHelper>().HasBeenInTheBackrooms)
			{
				if (__instance.allPlayerScripts[i].isPlayerDead)
				{
					__instance.gameStats.allPlayerStats[i].playerNotes.Add("Should have been more careful in the Backrooms.");
				}
				else
				{
					__instance.gameStats.allPlayerStats[i].playerNotes.Add("Had a blast in the Backrooms.");
				}
			}
		}
	}

	[HarmonyPatch(typeof(MenuManager), "Start")]
	[HarmonyPostfix]
	public static void NetworkManagerPatch(MenuManager __instance)
	{
		if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs.Select((NetworkPrefab pref) => ((Object)pref.Prefab).name).Contains("backrooms"))
		{
			Debug.Log((object)"Load prefabs to Network Manager");
			string[] array = new string[2] { "assets/backrooms/backrooms.prefab", "assets/backrooms/smile.prefab" };
			foreach (string text in array)
			{
				GameObject val = Loader.AssetBundle.LoadAsset<GameObject>(text);
				NetworkManager.Singleton.AddNetworkPrefab(val);
			}
		}
	}
}
[BepInPlugin("Neekhaulas.Backrooms", "Backrooms", "0.1.3")]
public class Loader : BaseUnityPlugin
{
	public static AssetBundle AssetBundle { get; private set; }

	public static ConfigEntry<float> TeleportationOdds { get; private set; }

	public static ConfigEntry<int> NumberOfSmilers { get; private set; }

	private void Awake()
	{
		TeleportationOdds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Teleportation odds", 3f, "Odds to be teleported (in %) - This settings has to be changed by the host");
		NumberOfSmilers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Number of smilers", 1, "Number of smilers to spawn in the Backrooms - This settings has to be changed by the host");
		AssetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "backrooms"));
		Harmony.CreateAndPatchAll(typeof(Hook), (string)null);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Backrooms is loaded!");
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		for (int i = 0; i < types.Length; i++)
		{
			MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
				{
					methodInfo.Invoke(null, null);
				}
			}
		}
	}
}
public class SoundPatch : MonoBehaviour
{
	private void Start()
	{
		((Component)this).gameObject.AddComponent<OccludeAudio>();
		((Component)this).GetComponent<AudioSource>().Play();
	}
}
public class Smiler : NetworkBehaviour
{
	private NavMeshAgent NavMeshAgent;

	private PlayerControllerB Target;

	private void Start()
	{
		NavMeshAgent = ((Component)this).GetComponent<NavMeshAgent>();
	}

	private void Update()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		if (!((NetworkBehaviour)this).IsServer)
		{
			return;
		}
		if ((Object)(object)Target != (Object)null && Target.isPlayerDead)
		{
			Target = null;
			NavMeshAgent.speed = 2f;
		}
		if (!NavMeshAgent.pathPending && NavMeshAgent.remainingDistance <= NavMeshAgent.stoppingDistance)
		{
			if (NavMeshAgent.hasPath)
			{
				Vector3 velocity = NavMeshAgent.velocity;
				if (((Vector3)(ref velocity)).sqrMagnitude != 0f)
				{
					goto IL_00f0;
				}
			}
			if ((Object)(object)Target != (Object)null)
			{
				NavMeshAgent.SetDestination(((Component)Target).transform.position);
			}
			else
			{
				int index = Random.Range(0, Backrooms.Instance.PossibleSpawnPoint.Count);
				NavMeshAgent.SetDestination(Vector2.op_Implicit(Backrooms.Instance.PossibleSpawnPoint[index]));
			}
		}
		goto IL_00f0;
		IL_00f0:
		for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
		{
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
			if (val.isPlayerControlled && !val.isPlayerDead)
			{
				if (val.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up, 45f, 15, -1f))
				{
					Target = val;
					NavMeshAgent.SetDestination(((Component)val).transform.position);
					NavMeshAgent.speed = 7f;
					break;
				}
				bool flag = false;
				if ((Object)(object)val.currentlyHeldObjectServer != (Object)null && ((object)val.currentlyHeldObjectServer).GetType() == typeof(FlashlightItem) && val.currentlyHeldObjectServer.isBeingUsed)
				{
					flag = true;
				}
				if ((Object)(object)val.pocketedFlashlight != (Object)null && ((object)val.pocketedFlashlight).GetType() == typeof(FlashlightItem) && val.pocketedFlashlight.isBeingUsed)
				{
					flag = true;
				}
				if (flag && val.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up, 45f, 100, -1f))
				{
					Target = val;
					NavMeshAgent.SetDestination(((Component)val).transform.position);
					NavMeshAgent.speed = 7f;
				}
			}
		}
	}

	protected override void __initializeVariables()
	{
		((NetworkBehaviour)this).__initializeVariables();
	}

	protected internal override string __getTypeName()
	{
		return "Smiler";
	}
}

BepInEx/plugins/LethalThings/LethalThings.dll

Decompiled 8 months 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.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalLib.Extras;
using LethalLib.Modules;
using LethalThings.Extensions;
using LethalThings.MonoBehaviours;
using LethalThings.Patches;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using On;
using On.GameNetcodeStuff;
using TMPro;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("LethalThings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+86ae65aa973bc30ae45609c9c37649bfb7da4c59")]
[assembly: AssemblyProduct("LethalThings")]
[assembly: AssemblyTitle("LethalThings")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<Vector3>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<Vector3>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<HackingTool.HackState>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals<HackingTool.HackState>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalLib.Modules
{
	public class SaveData
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ResetSavedGameValues <0>__GameNetworkManager_ResetSavedGameValues;

			public static hook_SaveItemsInShip <1>__GameNetworkManager_SaveItemsInShip;

			public static hook_LoadShipGrabbableItems <2>__StartOfRound_LoadShipGrabbableItems;
		}

		public static List<string> saveKeys = new List<string>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__GameNetworkManager_ResetSavedGameValues;
			if (obj == null)
			{
				hook_ResetSavedGameValues val = GameNetworkManager_ResetSavedGameValues;
				<>O.<0>__GameNetworkManager_ResetSavedGameValues = val;
				obj = (object)val;
			}
			GameNetworkManager.ResetSavedGameValues += (hook_ResetSavedGameValues)obj;
			object obj2 = <>O.<1>__GameNetworkManager_SaveItemsInShip;
			if (obj2 == null)
			{
				hook_SaveItemsInShip val2 = GameNetworkManager_SaveItemsInShip;
				<>O.<1>__GameNetworkManager_SaveItemsInShip = val2;
				obj2 = (object)val2;
			}
			GameNetworkManager.SaveItemsInShip += (hook_SaveItemsInShip)obj2;
			object obj3 = <>O.<2>__StartOfRound_LoadShipGrabbableItems;
			if (obj3 == null)
			{
				hook_LoadShipGrabbableItems val3 = StartOfRound_LoadShipGrabbableItems;
				<>O.<2>__StartOfRound_LoadShipGrabbableItems = val3;
				obj3 = (object)val3;
			}
			StartOfRound.LoadShipGrabbableItems += (hook_LoadShipGrabbableItems)obj3;
		}

		private static void StartOfRound_LoadShipGrabbableItems(orig_LoadShipGrabbableItems orig, StartOfRound self)
		{
			orig.Invoke(self);
			SaveableObject[] array = Object.FindObjectsOfType<SaveableObject>();
			SaveableNetworkBehaviour[] array2 = Object.FindObjectsOfType<SaveableNetworkBehaviour>();
			SaveableObject[] array3 = array;
			for (int i = 0; i < array3.Length; i++)
			{
				array3[i].LoadObjectData();
			}
			SaveableNetworkBehaviour[] array4 = array2;
			for (int i = 0; i < array4.Length; i++)
			{
				array4[i].LoadObjectData();
			}
			if (ES3.KeyExists("LethalLibItemSaveKeys", GameNetworkManager.Instance.currentSaveFileName))
			{
				saveKeys = ES3.Load<List<string>>("LethalLibItemSaveKeys", GameNetworkManager.Instance.currentSaveFileName);
			}
		}

		private static void GameNetworkManager_SaveItemsInShip(orig_SaveItemsInShip orig, GameNetworkManager self)
		{
			orig.Invoke(self);
			SaveableObject[] array = Object.FindObjectsOfType<SaveableObject>();
			SaveableNetworkBehaviour[] array2 = Object.FindObjectsOfType<SaveableNetworkBehaviour>();
			SaveableObject[] array3 = array;
			for (int i = 0; i < array3.Length; i++)
			{
				array3[i].SaveObjectData();
			}
			SaveableNetworkBehaviour[] array4 = array2;
			for (int i = 0; i < array4.Length; i++)
			{
				array4[i].SaveObjectData();
			}
			ES3.Save<List<string>>("LethalLibItemSaveKeys", saveKeys, GameNetworkManager.Instance.currentSaveFileName);
		}

		private static void GameNetworkManager_ResetSavedGameValues(orig_ResetSavedGameValues orig, GameNetworkManager self)
		{
			orig.Invoke(self);
			foreach (string saveKey in saveKeys)
			{
				ES3.DeleteKey(saveKey, GameNetworkManager.Instance.currentSaveFileName);
			}
			saveKeys.Clear();
		}

		public static void SaveObjectData<T>(string key, T data, int objectId)
		{
			List<T> list = new List<T>();
			if (ES3.KeyExists("LethalThingsSave_" + key, GameNetworkManager.Instance.currentSaveFileName))
			{
				list = ES3.Load<List<T>>("LethalThingsSave_" + key, GameNetworkManager.Instance.currentSaveFileName);
			}
			List<int> list2 = new List<int>();
			if (ES3.KeyExists("LethalThingsSave_objectIds_" + key, GameNetworkManager.Instance.currentSaveFileName))
			{
				list2 = ES3.Load<List<int>>("LethalThingsSave_objectIds_" + key, GameNetworkManager.Instance.currentSaveFileName);
			}
			list.Add(data);
			list2.Add(objectId);
			if (!saveKeys.Contains("LethalThingsSave_" + key))
			{
				saveKeys.Add("LethalThingsSave_" + key);
			}
			if (!saveKeys.Contains("LethalThingsSave_objectIds_" + key))
			{
				saveKeys.Add("LethalThingsSave_objectIds_" + key);
			}
			ES3.Save<List<T>>("LethalThingsSave_" + key, list, GameNetworkManager.Instance.currentSaveFileName);
			ES3.Save<List<int>>("LethalThingsSave_objectIds_" + key, list2, GameNetworkManager.Instance.currentSaveFileName);
		}

		public static T LoadObjectData<T>(string key, int objectId)
		{
			List<T> list = new List<T>();
			if (ES3.KeyExists("LethalThingsSave_" + key, GameNetworkManager.Instance.currentSaveFileName))
			{
				list = ES3.Load<List<T>>("LethalThingsSave_" + key, GameNetworkManager.Instance.currentSaveFileName);
			}
			List<int> list2 = new List<int>();
			if (ES3.KeyExists("LethalThingsSave_objectIds_" + key, GameNetworkManager.Instance.currentSaveFileName))
			{
				list2 = ES3.Load<List<int>>("LethalThingsSave_objectIds_" + key, GameNetworkManager.Instance.currentSaveFileName);
			}
			if (!saveKeys.Contains("LethalThingsSave_" + key))
			{
				saveKeys.Add("LethalThingsSave_" + key);
			}
			if (!saveKeys.Contains("LethalThingsSave_objectIds_" + key))
			{
				saveKeys.Add("LethalThingsSave_objectIds_" + key);
			}
			if (list2.Contains(objectId))
			{
				int index = list2.IndexOf(objectId);
				return list[index];
			}
			return default(T);
		}
	}
}
namespace LethalThings
{
	public class Config
	{
		public static ConfigEntry<int> arsonSpawnWeight;

		public static ConfigEntry<int> dirtyArsonSpawnWeight;

		public static ConfigEntry<int> toimariSpawnWeight;

		public static ConfigEntry<int> hamisSpawnWeight;

		public static ConfigEntry<int> cookieSpawnWeight;

		public static ConfigEntry<int> maxwellSpawnWeight;

		public static ConfigEntry<float> evilMaxwellChance;

		public static ConfigEntry<bool> maxwellPlayMusicDefault;

		public static ConfigEntry<int> glizzySpawnChance;

		public static ConfigEntry<int> revolverSpawnChance;

		public static ConfigEntry<int> gremlinSodaSpawnChance;

		public static ConfigEntry<bool> toyHammerEnabled;

		public static ConfigEntry<int> toyHammerPrice;

		public static ConfigEntry<bool> pouchyBeltEnabled;

		public static ConfigEntry<int> pouchyBeltPrice;

		public static ConfigEntry<bool> remoteRadarEnabled;

		public static ConfigEntry<int> remoteRadarPrice;

		public static ConfigEntry<bool> rocketLauncherEnabled;

		public static ConfigEntry<int> rocketLauncherPrice;

		public static ConfigEntry<bool> hackingToolEnabled;

		public static ConfigEntry<int> hackingToolPrice;

		public static ConfigEntry<bool> flareGunEnabled;

		public static ConfigEntry<int> flareGunPrice;

		public static ConfigEntry<int> flareGunAmmoPrice;

		public static ConfigEntry<int> boombaSpawnWeight;

		public static ConfigEntry<bool> rugsEnabled;

		public static ConfigEntry<int> smallRugPrice;

		public static ConfigEntry<int> largeRugPrice;

		public static ConfigEntry<bool> fatalitiesSignEnabled;

		public static ConfigEntry<int> fatalitiesSignPrice;

		public static ConfigEntry<bool> dartBoardEnabled;

		public static ConfigEntry<int> dartBoardPrice;

		public static ConfigEntry<bool> teleporterTrapsEnabled;

		public static ConfigEntry<bool> enableItemChargerElectrocution;

		public static ConfigEntry<int> itemChargerElectrocutionDamage;

		public static ConfigEntry<bool> disableOverlappingModContent;

		public static ConfigFile VolumeConfig;

		public static ConfigEntry<string> version;

		public static void Load()
		{
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Expected O, but got Unknown
			arsonSpawnWeight = Plugin.config.Bind<int>("Scrap", "Arson", 5, "How much does Arson spawn, higher = more common");
			dirtyArsonSpawnWeight = Plugin.config.Bind<int>("Scrap", "DirtyArson", 5, "How much does Arson (Dirty) spawn, higher = more common");
			toimariSpawnWeight = Plugin.config.Bind<int>("Scrap", "Toimari", 10, "How much does Toimari spawn, higher = more common");
			hamisSpawnWeight = Plugin.config.Bind<int>("Scrap", "Hamis", 10, "How much does Hamis spawn, higher = more common");
			cookieSpawnWeight = Plugin.config.Bind<int>("Scrap", "Cookie", 10, "How much does Cookie spawn, higher = more common");
			maxwellSpawnWeight = Plugin.config.Bind<int>("Scrap", "Maxwell", 3, "How much does Maxwell spawn, higher = more common");
			evilMaxwellChance = Plugin.config.Bind<float>("Scrap", "MaxwellEvilChance", 10f, "Chance for maxwell to be evil, percentage.");
			maxwellPlayMusicDefault = Plugin.config.Bind<bool>("Scrap", "MaxwellPlayMusicDefault", true, "Does Maxwell play music by default?");
			glizzySpawnChance = Plugin.config.Bind<int>("Scrap", "GlizzySpawnChance", 5, "How much do glizzies spawn, higher = more common");
			revolverSpawnChance = Plugin.config.Bind<int>("Scrap", "Revolver", 10, "How much do revolvers spawn, higher = more common");
			gremlinSodaSpawnChance = Plugin.config.Bind<int>("Scrap", "GremlinEnergyDrink", 10, "How much does Gremlin Energy Drink spawn, higher = more common");
			toyHammerEnabled = Plugin.config.Bind<bool>("Items", "ToyHammer", true, "Is Toy Hammer enabled?");
			toyHammerPrice = Plugin.config.Bind<int>("Items", "ToyHammerPrice", 15, "How much does Toy Hammer cost?");
			pouchyBeltEnabled = Plugin.config.Bind<bool>("Items", "PouchyBelt", true, "Is Pouchy Belt enabled?");
			pouchyBeltPrice = Plugin.config.Bind<int>("Items", "PouchyBeltPrice", 290, "How much does Pouchy Belt cost?");
			remoteRadarEnabled = Plugin.config.Bind<bool>("Items", "RemoteRadar", true, "Is Remote Radar enabled?");
			remoteRadarPrice = Plugin.config.Bind<int>("Items", "RemoteRadarPrice", 150, "How much does Remote Radar cost?");
			rocketLauncherEnabled = Plugin.config.Bind<bool>("Items", "RocketLauncher", true, "Is Rocket Launcher enabled?");
			rocketLauncherPrice = Plugin.config.Bind<int>("Items", "RocketLauncherPrice", 300, "How much does Rocket Launcher cost?");
			hackingToolEnabled = Plugin.config.Bind<bool>("Items", "HackingTool", true, "Is Hacking Tool enabled?");
			hackingToolPrice = Plugin.config.Bind<int>("Items", "HackingToolPrice", 120, "How much does Hacking Tool cost?");
			flareGunEnabled = Plugin.config.Bind<bool>("Items", "FlareGun", true, "Is Flare Gun enabled?");
			flareGunPrice = Plugin.config.Bind<int>("Items", "FlareGunPrice", 100, "How much does Flare Gun cost?");
			flareGunAmmoPrice = Plugin.config.Bind<int>("Items", "FlareGunAmmoPrice", 20, "How much does Flare Gun ammo cost?");
			boombaSpawnWeight = Plugin.config.Bind<int>("Enemies", "Boomba", 20, "How much does Boomba spawn, higher = more common");
			rugsEnabled = Plugin.config.Bind<bool>("Decor", "Rugs", true, "Are rugs enabled?");
			smallRugPrice = Plugin.config.Bind<int>("Decor", "SmallRugPrice", 80, "How much does a small rug cost?");
			largeRugPrice = Plugin.config.Bind<int>("Decor", "LargeRugPrice", 110, "How much does a large rug cost?");
			fatalitiesSignEnabled = Plugin.config.Bind<bool>("Decor", "FatalitiesSign", true, "Is Fatalities Sign enabled?");
			fatalitiesSignPrice = Plugin.config.Bind<int>("Decor", "FatalitiesSignPrice", 100, "How much does Fatalities Sign cost?");
			dartBoardEnabled = Plugin.config.Bind<bool>("Decor", "DartBoard", true, "Is Dart Board enabled?");
			dartBoardPrice = Plugin.config.Bind<int>("Decor", "DartBoardPrice", 120, "How much does Dart Board cost?");
			teleporterTrapsEnabled = Plugin.config.Bind<bool>("Traps", "TeleporterTraps", true, "Are teleporter traps enabled?");
			enableItemChargerElectrocution = Plugin.config.Bind<bool>("Misc", "EnableItemChargerElectrocution", true, "Do players get electrocuted when stuffing conductive objects in the item charger.");
			itemChargerElectrocutionDamage = Plugin.config.Bind<int>("Misc", "ItemChargerElectrocutionDamage", 20, "How much damage does the item charger electrocution do.");
			disableOverlappingModContent = Plugin.config.Bind<bool>("Misc", "DisableOverlappingModContent", true, "Disable content from other mods which exists in this one (e.g. maxwell).");
			version = Plugin.config.Bind<string>("Misc", "Version", "1.0.0", "Version of the mod config.");
			VolumeConfig = new ConfigFile(Paths.ConfigPath + "\\LethalThings.AudioVolume.cfg", true);
		}
	}
	public class Content
	{
		public class CustomItem
		{
			public string name = "";

			public string itemPath = "";

			public string infoPath = "";

			public Action<Item> itemAction = delegate
			{
			};

			public bool enabled = true;

			public CustomItem(string name, string itemPath, string infoPath, Action<Item> action = null)
			{
				this.name = name;
				this.itemPath = itemPath;
				this.infoPath = infoPath;
				if (action != null)
				{
					itemAction = action;
				}
			}

			public static CustomItem Add(string name, string itemPath, string infoPath = null, Action<Item> action = null)
			{
				return new CustomItem(name, itemPath, infoPath, action);
			}
		}

		public class CustomUnlockable
		{
			public string name = "";

			public string unlockablePath = "";

			public string infoPath = "";

			public Action<UnlockableItem> unlockableAction = delegate
			{
			};

			public bool enabled = true;

			public int unlockCost = -1;

			public CustomUnlockable(string name, string unlockablePath, string infoPath, Action<UnlockableItem> action = null, int unlockCost = -1)
			{
				this.name = name;
				this.unlockablePath = unlockablePath;
				this.infoPath = infoPath;
				if (action != null)
				{
					unlockableAction = action;
				}
				this.unlockCost = unlockCost;
			}

			public static CustomUnlockable Add(string name, string unlockablePath, string infoPath = null, Action<UnlockableItem> action = null, int unlockCost = -1, bool enabled = true)
			{
				return new CustomUnlockable(name, unlockablePath, infoPath, action, unlockCost)
				{
					enabled = enabled
				};
			}
		}

		public class CustomShopItem : CustomItem
		{
			public int itemPrice;

			public CustomShopItem(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null)
				: base(name, itemPath, infoPath, action)
			{
				this.itemPrice = itemPrice;
			}

			public static CustomShopItem Add(string name, string itemPath, string infoPath = null, int itemPrice = 0, Action<Item> action = null, bool enabled = true)
			{
				return new CustomShopItem(name, itemPath, infoPath, itemPrice, action)
				{
					enabled = enabled
				};
			}
		}

		public class CustomScrap : CustomItem
		{
			public LevelTypes levelType = (LevelTypes)510;

			public int rarity;

			public CustomScrap(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null)
				: base(name, itemPath, null, action)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: 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)
				this.levelType = levelType;
				this.rarity = rarity;
			}

			public static CustomScrap Add(string name, string itemPath, LevelTypes levelType, int rarity, Action<Item> action = null)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				return new CustomScrap(name, itemPath, levelType, rarity, action);
			}
		}

		public class CustomPlainItem : CustomItem
		{
			public CustomPlainItem(string name, string itemPath, Action<Item> action = null)
				: base(name, itemPath, null, action)
			{
			}

			public static CustomPlainItem Add(string name, string itemPath, Action<Item> action = null)
			{
				return new CustomPlainItem(name, itemPath, action);
			}
		}

		public class CustomEnemy
		{
			public string name;

			public string enemyPath;

			public int rarity;

			public LevelTypes levelFlags;

			public SpawnType spawnType;

			public string infoKeyword;

			public string infoNode;

			public bool enabled = true;

			public CustomEnemy(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.enemyPath = enemyPath;
				this.rarity = rarity;
				this.levelFlags = levelFlags;
				this.spawnType = spawnType;
				this.infoKeyword = infoKeyword;
				this.infoNode = infoNode;
			}

			public static CustomEnemy Add(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode, bool enabled = true)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				return new CustomEnemy(name, enemyPath, rarity, levelFlags, spawnType, infoKeyword, infoNode)
				{
					enabled = enabled
				};
			}
		}

		public class CustomMapObject
		{
			public string name;

			public string objectPath;

			public LevelTypes levelFlags;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public bool enabled = true;

			public CustomMapObject(string name, string objectPath, LevelTypes levelFlags, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, bool enabled = false)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.objectPath = objectPath;
				this.levelFlags = levelFlags;
				this.spawnRateFunction = spawnRateFunction;
				this.enabled = enabled;
			}

			public static CustomMapObject Add(string name, string objectPath, LevelTypes levelFlags, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, bool enabled = false)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				return new CustomMapObject(name, objectPath, levelFlags, spawnRateFunction, enabled);
			}
		}

		public static AssetBundle MainAssets;

		public static Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		public static GameObject devMenuPrefab;

		public static List<CustomUnlockable> customUnlockables;

		public static List<CustomItem> customItems;

		public static List<CustomEnemy> customEnemies;

		public static List<CustomMapObject> customMapObjects;

		public static GameObject ConfigManagerPrefab;

		public static void TryLoadAssets()
		{
			if ((Object)(object)MainAssets == (Object)null)
			{
				MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lethalthings"));
				Plugin.logger.LogInfo((object)"Loaded asset bundle");
			}
		}

		public static void Load()
		{
			//IL_0583: Unknown result type (might be due to invalid IL or missing references)
			//IL_070f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0716: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a5: Unknown result type (might be due to invalid IL or missing references)
			TryLoadAssets();
			customItems = new List<CustomItem>
			{
				CustomScrap.Add("Arson", "Assets/Custom/LethalThings/Scrap/Arson/ArsonPlush.asset", (LevelTypes)510, Config.arsonSpawnWeight.Value),
				CustomScrap.Add("Cookie", "Assets/Custom/LethalThings/Scrap/Cookie/CookieFumo.asset", (LevelTypes)510, Config.cookieSpawnWeight.Value),
				CustomScrap.Add("Bilka", "Assets/Custom/LethalThings/Scrap/Toimari/ToimariPlush.asset", (LevelTypes)510, Config.toimariSpawnWeight.Value),
				CustomScrap.Add("Hamis", "Assets/Custom/LethalThings/Scrap/Hamis/HamisPlush.asset", (LevelTypes)510, Config.hamisSpawnWeight.Value),
				CustomScrap.Add("ArsonDirty", "Assets/Custom/LethalThings/Scrap/Arson/ArsonPlushDirty.asset", (LevelTypes)510, Config.dirtyArsonSpawnWeight.Value),
				CustomScrap.Add("Maxwell", "Assets/Custom/LethalThings/Scrap/Maxwell/Dingus.asset", (LevelTypes)510, Config.maxwellSpawnWeight.Value),
				CustomScrap.Add("Glizzy", "Assets/Custom/LethalThings/Scrap/glizzy/glizzy.asset", (LevelTypes)510, Config.glizzySpawnChance.Value),
				CustomScrap.Add("Revolver", "Assets/Custom/LethalThings/Scrap/Flaggun/Toygun.asset", (LevelTypes)510, Config.revolverSpawnChance.Value),
				CustomShopItem.Add("RocketLauncher", "Assets/Custom/LethalThings/Items/RocketLauncher/RocketLauncher.asset", "Assets/Custom/LethalThings/Items/RocketLauncher/RocketLauncherInfo.asset", Config.rocketLauncherPrice.Value, delegate(Item item)
				{
					NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab.GetComponent<RocketLauncher>().missilePrefab);
				}, Config.rocketLauncherEnabled.Value),
				CustomShopItem.Add("Flaregun", "Assets/Custom/LethalThings/Items/Flaregun/Flaregun.asset", "Assets/Custom/LethalThings/Items/Flaregun/FlaregunInfo.asset", Config.flareGunPrice.Value, delegate(Item item)
				{
					NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab.GetComponent<ProjectileWeapon>().projectilePrefab);
				}, Config.flareGunEnabled.Value),
				CustomShopItem.Add("FlaregunAmmo", "Assets/Custom/LethalThings/Items/Flaregun/FlaregunAmmo.asset", "Assets/Custom/LethalThings/Items/Flaregun/FlaregunAmmoInfo.asset", Config.flareGunAmmoPrice.Value, null, Config.flareGunEnabled.Value),
				CustomShopItem.Add("ToyHammer", "Assets/Custom/LethalThings/Items/ToyHammer/ToyHammer.asset", "Assets/Custom/LethalThings/Items/ToyHammer/ToyHammerInfo.asset", Config.toyHammerPrice.Value, null, Config.toyHammerEnabled.Value),
				CustomShopItem.Add("RemoteRadar", "Assets/Custom/LethalThings/Items/Radar/HandheldRadar.asset", "Assets/Custom/LethalThings/Items/Radar/HandheldRadarInfo.asset", Config.remoteRadarPrice.Value, null, Config.remoteRadarEnabled.Value),
				CustomShopItem.Add("PouchyBelt", "Assets/Custom/LethalThings/Items/Pouch/Pouch.asset", "Assets/Custom/LethalThings/Items/Pouch/PouchInfo.asset", Config.pouchyBeltPrice.Value, null, Config.pouchyBeltEnabled.Value),
				CustomShopItem.Add("HackingTool", "Assets/Custom/LethalThings/Items/HackingTool/HackingTool.asset", "Assets/Custom/LethalThings/Items/HackingTool/HackingToolInfo.asset", Config.hackingToolPrice.Value, null, Config.hackingToolEnabled.Value),
				CustomPlainItem.Add("Dart", "Assets/Custom/LethalThings/Unlockables/dartboard/Dart.asset"),
				CustomScrap.Add("GremlinEnergy", "Assets/Custom/LethalThings/Scrap/GremlinEnergy/GremlinEnergy.asset", (LevelTypes)510, Config.gremlinSodaSpawnChance.Value)
			};
			customEnemies = new List<CustomEnemy> { CustomEnemy.Add("Boomba", "Assets/Custom/LethalThings/Enemies/Roomba/Boomba.asset", Config.boombaSpawnWeight.Value, (LevelTypes)510, (SpawnType)0, null, "Assets/Custom/LethalThings/Enemies/Roomba/BoombaFile.asset") };
			customUnlockables = new List<CustomUnlockable>
			{
				CustomUnlockable.Add("SmallRug", "Assets/Custom/LethalThings/Unlockables/Rug/SmallRug.asset", "Assets/Custom/LethalThings/Unlockables/Rug/RugInfo.asset", null, Config.smallRugPrice.Value, Config.rugsEnabled.Value),
				CustomUnlockable.Add("LargeRug", "Assets/Custom/LethalThings/Unlockables/Rug/LargeRug.asset", "Assets/Custom/LethalThings/Unlockables/Rug/RugInfo.asset", null, Config.largeRugPrice.Value, Config.rugsEnabled.Value),
				CustomUnlockable.Add("FatalitiesSign", "Assets/Custom/LethalThings/Unlockables/Sign/Sign.asset", "Assets/Custom/LethalThings/Unlockables/Sign/SignInfo.asset", null, Config.fatalitiesSignPrice.Value, Config.fatalitiesSignEnabled.Value),
				CustomUnlockable.Add("Dartboard", "Assets/Custom/LethalThings/Unlockables/dartboard/Dartboard.asset", "Assets/Custom/LethalThings/Unlockables/dartboard/DartboardInfo.asset", null, Config.dartBoardPrice.Value, Config.dartBoardEnabled.Value)
			};
			customMapObjects = new List<CustomMapObject> { CustomMapObject.Add("TeleporterTrap", "Assets/Custom/LethalThings/hazards/TeleporterTrap/TeleporterTrap.asset", (LevelTypes)510, (SelectableLevel level) => new AnimationCurve((Keyframe[])(object)new Keyframe[2]
			{
				new Keyframe(0f, 0f),
				new Keyframe(1f, 4f)
			}), Config.teleporterTrapsEnabled.Value) };
			foreach (CustomItem customItem in customItems)
			{
				if (customItem.enabled)
				{
					Item val = MainAssets.LoadAsset<Item>(customItem.itemPath);
					if ((Object)(object)val.spawnPrefab.GetComponent<NetworkTransform>() == (Object)null && (Object)(object)val.spawnPrefab.GetComponent<CustomNetworkTransform>() == (Object)null)
					{
						NetworkTransform obj = val.spawnPrefab.AddComponent<NetworkTransform>();
						obj.SlerpPosition = false;
						obj.Interpolate = false;
						obj.SyncPositionX = false;
						obj.SyncPositionY = false;
						obj.SyncPositionZ = false;
						obj.SyncScaleX = false;
						obj.SyncScaleY = false;
						obj.SyncScaleZ = false;
						obj.UseHalfFloatPrecision = true;
					}
					Prefabs.Add(customItem.name, val.spawnPrefab);
					NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
					customItem.itemAction(val);
					if (customItem is CustomShopItem)
					{
						TerminalNode val2 = MainAssets.LoadAsset<TerminalNode>(customItem.infoPath);
						Plugin.logger.LogInfo((object)$"Registering shop item {customItem.name} with price {((CustomShopItem)customItem).itemPrice}");
						Items.RegisterShopItem(val, (TerminalNode)null, (TerminalNode)null, val2, ((CustomShopItem)customItem).itemPrice);
					}
					else if (customItem is CustomScrap)
					{
						Items.RegisterScrap(val, ((CustomScrap)customItem).rarity, ((CustomScrap)customItem).levelType);
					}
					else if (customItem is CustomPlainItem)
					{
						Items.RegisterItem(val);
					}
				}
			}
			foreach (CustomUnlockable customUnlockable in customUnlockables)
			{
				if (customUnlockable.enabled)
				{
					UnlockableItem unlockable = MainAssets.LoadAsset<UnlockableItemDef>(customUnlockable.unlockablePath).unlockable;
					if ((Object)(object)unlockable.prefabObject != (Object)null)
					{
						NetworkPrefabs.RegisterNetworkPrefab(unlockable.prefabObject);
					}
					Prefabs.Add(customUnlockable.name, unlockable.prefabObject);
					TerminalNode val3 = null;
					if (customUnlockable.infoPath != null)
					{
						val3 = MainAssets.LoadAsset<TerminalNode>(customUnlockable.infoPath);
					}
					Unlockables.RegisterUnlockable(unlockable, (StoreType)2, (TerminalNode)null, (TerminalNode)null, val3, customUnlockable.unlockCost);
				}
			}
			foreach (CustomEnemy customEnemy in customEnemies)
			{
				if (customEnemy.enabled)
				{
					EnemyType val4 = MainAssets.LoadAsset<EnemyType>(customEnemy.enemyPath);
					TerminalNode val5 = MainAssets.LoadAsset<TerminalNode>(customEnemy.infoNode);
					TerminalKeyword val6 = null;
					if (customEnemy.infoKeyword != null)
					{
						val6 = MainAssets.LoadAsset<TerminalKeyword>(customEnemy.infoKeyword);
					}
					NetworkPrefabs.RegisterNetworkPrefab(val4.enemyPrefab);
					Prefabs.Add(customEnemy.name, val4.enemyPrefab);
					Enemies.RegisterEnemy(val4, customEnemy.rarity, customEnemy.levelFlags, customEnemy.spawnType, val5, val6);
				}
			}
			foreach (CustomMapObject customMapObject in customMapObjects)
			{
				if (customMapObject.enabled)
				{
					SpawnableMapObjectDef val7 = MainAssets.LoadAsset<SpawnableMapObjectDef>(customMapObject.objectPath);
					NetworkPrefabs.RegisterNetworkPrefab(val7.spawnableMapObject.prefabToSpawn);
					Prefabs.Add(customMapObject.name, val7.spawnableMapObject.prefabToSpawn);
					MapObjects.RegisterMapObject(val7, customMapObject.levelFlags, customMapObject.spawnRateFunction);
				}
			}
			foreach (KeyValuePair<string, GameObject> prefab in Prefabs)
			{
				GameObject value = prefab.Value;
				string key = prefab.Key;
				AudioSource[] componentsInChildren = value.GetComponentsInChildren<AudioSource>();
				if (componentsInChildren.Length != 0)
				{
					ConfigEntry<float> val8 = Config.VolumeConfig.Bind<float>("Volume", key ?? "", 100f, "Audio volume for " + key + " (0 - 100)");
					AudioSource[] array = componentsInChildren;
					foreach (AudioSource obj2 in array)
					{
						obj2.volume *= val8.Value / 100f;
					}
				}
			}
			GameObject obj3 = MainAssets.LoadAsset<GameObject>("Assets/Custom/LethalThings/DevMenu.prefab");
			NetworkPrefabs.RegisterNetworkPrefab(obj3);
			devMenuPrefab = obj3;
			try
			{
				foreach (Type loadableType in Assembly.GetExecutingAssembly().GetLoadableTypes())
				{
					MethodInfo[] methods = loadableType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
						{
							methodInfo.Invoke(null, null);
						}
					}
				}
			}
			catch (Exception)
			{
			}
			Plugin.logger.LogInfo((object)"Custom content loaded!");
		}
	}
	public static class InputCompat
	{
		public static InputActionAsset Asset;

		public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.LethalCompanyInputUtils");

		public static InputAction LTUtilityBeltQuick1 => Keybinds.Instance.LTUtilityBeltQuick1;

		public static InputAction LTUtilityBeltQuick2 => Keybinds.Instance.LTUtilityBeltQuick2;

		public static InputAction LTUtilityBeltQuick3 => Keybinds.Instance.LTUtilityBeltQuick3;

		public static InputAction LTUtilityBeltQuick4 => Keybinds.Instance.LTUtilityBeltQuick4;

		public static void Init()
		{
			Keybinds.Instance = new Keybinds();
			Asset = Keybinds.Instance.GetAsset();
		}
	}
	public class Keybinds : LcInputActions
	{
		public static Keybinds Instance;

		[InputAction("", Name = "[LT] Utility Belt Quick 1")]
		public InputAction LTUtilityBeltQuick1 { get; set; }

		[InputAction("", Name = "[LT] Utility Belt Quick 2")]
		public InputAction LTUtilityBeltQuick2 { get; set; }

		[InputAction("", Name = "[LT] Utility Belt Quick 3")]
		public InputAction LTUtilityBeltQuick3 { get; set; }

		[InputAction("", Name = "[LT] Utility Belt Quick 4")]
		public InputAction LTUtilityBeltQuick4 { get; set; }

		public InputActionAsset GetAsset()
		{
			return ((LcInputActions)this).Asset;
		}
	}
	public class Dingus : SaveableObject
	{
		public AudioSource noiseAudio;

		public AudioSource noiseAudioFar;

		public AudioSource musicAudio;

		public AudioSource musicAudioFar;

		[Space(3f)]
		public AudioClip[] noiseSFX;

		public AudioClip[] noiseSFXFar;

		public AudioClip evilNoise;

		[Space(3f)]
		public float noiseRange;

		public float maxLoudness;

		public float minLoudness;

		public float minPitch;

		public float maxPitch;

		private Random noisemakerRandom;

		public Animator triggerAnimator;

		private int timesPlayedWithoutTurningOff;

		private RoundManager roundManager;

		private float noiseInterval = 1f;

		public Animator danceAnimator;

		public bool wasLoadedFromSave;

		public bool exploding;

		private NetworkVariable<bool> isEvil = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public GameObject evilObject;

		public NetworkVariable<bool> isPlayingMusic = new NetworkVariable<bool>(Config.maxwellPlayMusicDefault.Value, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1);

		public NetworkVariable<bool> isPipebomb = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public override void SaveObjectData()
		{
			SaveData.SaveObjectData("dingusBeEvil", isEvil.Value, uniqueId);
		}

		public override void LoadObjectData()
		{
			if (((NetworkBehaviour)this).IsHost)
			{
				bool flag = SaveData.LoadObjectData<bool>("dingusBeEvil", uniqueId);
				if (flag)
				{
					isEvil.Value = flag;
				}
			}
		}

		public override void Start()
		{
			((GrabbableObject)this).Start();
			roundManager = Object.FindObjectOfType<RoundManager>();
			noisemakerRandom = new Random(StartOfRound.Instance.randomMapSeed + 85);
			Debug.Log((object)"Making the dingus dance");
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			if (((NetworkBehaviour)this).IsOwner)
			{
				isPlayingMusic.Value = Config.maxwellPlayMusicDefault.Value;
			}
			if (((NetworkBehaviour)this).IsHost)
			{
				isEvil.Value = Random.Range(0f, 100f) <= Config.evilMaxwellChance.Value;
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				int num = noisemakerRandom.Next(0, noiseSFX.Length);
				float num2 = (float)noisemakerRandom.Next((int)(minLoudness * 100f), (int)(maxLoudness * 100f)) / 100f;
				float pitch = (float)noisemakerRandom.Next((int)(minPitch * 100f), (int)(maxPitch * 100f)) / 100f;
				noiseAudio.pitch = pitch;
				noiseAudio.PlayOneShot(noiseSFX[num], num2);
				if ((Object)(object)noiseAudioFar != (Object)null)
				{
					noiseAudioFar.pitch = pitch;
					noiseAudioFar.PlayOneShot(noiseSFXFar[num], num2);
				}
				if ((Object)(object)triggerAnimator != (Object)null)
				{
					triggerAnimator.SetTrigger("playAnim");
				}
				WalkieTalkie.TransmitOneShotAudio(noiseAudio, noiseSFX[num], num2);
				RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, noiseRange, num2, 0, ((GrabbableObject)this).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0);
			}
		}

		public override void DiscardItem()
		{
			if ((Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
			{
				((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = false;
			}
			((GrabbableObject)this).isBeingUsed = false;
			((GrabbableObject)this).DiscardItem();
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = true;
			danceAnimator.Play("dingusIdle");
			Debug.Log((object)"Making the dingus idle");
		}

		public override void ItemInteractLeftRight(bool right)
		{
			((GrabbableObject)this).ItemInteractLeftRight(right);
			if (!right && ((NetworkBehaviour)this).IsOwner)
			{
				isPlayingMusic.Value = !isPlayingMusic.Value;
			}
		}

		public override void InteractItem()
		{
			((GrabbableObject)this).InteractItem();
			if (isEvil.Value && !exploding && !isPipebomb.Value)
			{
				EvilMaxwellServerRpc();
			}
		}

		public void EvilMaxwellTruly()
		{
			danceAnimator.Play("dingusIdle");
			if (musicAudio.isPlaying)
			{
				musicAudio.Pause();
				musicAudioFar.Pause();
			}
			((MonoBehaviour)this).StartCoroutine(evilMaxwellMoment());
		}

		[ServerRpc(RequireOwnership = false)]
		public void EvilMaxwellServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(88404199u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 88404199u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					isPipebomb.Value = true;
					EvilMaxwellClientRpc();
				}
			}
		}

		[ClientRpc]
		public void EvilMaxwellClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1120322383u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1120322383u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				EvilMaxwellTruly();
				exploding = true;
				if (((NetworkBehaviour)this).IsOwner)
				{
					isPlayingMusic.Value = false;
				}
				timesPlayedWithoutTurningOff = 0;
				danceAnimator.Play("dingusIdle");
				if (musicAudio.isPlaying)
				{
					musicAudio.Pause();
					musicAudioFar.Pause();
				}
				Plugin.logger.LogInfo((object)"Evil maxwell moment");
			}
		}

		public IEnumerator evilMaxwellMoment()
		{
			yield return (object)new WaitForSeconds(1f);
			noiseAudio.PlayOneShot(evilNoise, 1f);
			evilObject.SetActive(true);
			((Renderer)((GrabbableObject)this).mainObjectRenderer).enabled = false;
			if ((Object)(object)noiseAudioFar != (Object)null)
			{
				noiseAudioFar.PlayOneShot(evilNoise, 1f);
			}
			if ((Object)(object)triggerAnimator != (Object)null)
			{
				triggerAnimator.SetTrigger("playAnim");
			}
			WalkieTalkie.TransmitOneShotAudio(noiseAudio, evilNoise, 1f);
			RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, noiseRange, 1f, 0, ((GrabbableObject)this).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0);
			yield return (object)new WaitForSeconds(1.5f);
			Utilities.CreateExplosion(((Component)this).transform.position, spawnExplosionEffect: true, 100, 0f, 6.4f, 6, (CauseOfDeath)3);
			Rigidbody[] componentsInChildren = evilObject.GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody obj in componentsInChildren)
			{
				obj.isKinematic = false;
				obj.AddExplosionForce(1000f, evilObject.transform.position, 100f);
			}
			yield return (object)new WaitForSeconds(2f);
			if (((NetworkBehaviour)this).IsServer)
			{
				((Component)this).GetComponent<NetworkObject>().Despawn(true);
			}
		}

		public override void Update()
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (isEvil.Value)
			{
				((GrabbableObject)this).grabbable = false;
				((GrabbableObject)this).grabbableToEnemies = false;
			}
			if (isPlayingMusic.Value && !exploding)
			{
				if (!musicAudio.isPlaying)
				{
					musicAudio.Play();
					musicAudioFar.Play();
				}
				if (!((GrabbableObject)this).isHeld)
				{
					danceAnimator.Play("dingusDance");
				}
				else
				{
					danceAnimator.Play("dingusIdle");
				}
				if (noiseInterval <= 0f)
				{
					noiseInterval = 1f;
					timesPlayedWithoutTurningOff++;
					roundManager.PlayAudibleNoise(((Component)this).transform.position, 16f, 0.9f, timesPlayedWithoutTurningOff, false, 5);
				}
				else
				{
					noiseInterval -= Time.deltaTime;
				}
			}
			else
			{
				timesPlayedWithoutTurningOff = 0;
				danceAnimator.Play("dingusIdle");
				if (musicAudio.isPlaying)
				{
					musicAudio.Pause();
					musicAudioFar.Pause();
				}
			}
		}

		protected override void __initializeVariables()
		{
			if (isEvil == null)
			{
				throw new Exception("Dingus.isEvil cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)isEvil).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)isEvil, "isEvil");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)isEvil);
			if (isPlayingMusic == null)
			{
				throw new Exception("Dingus.isPlayingMusic cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)isPlayingMusic).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)isPlayingMusic, "isPlayingMusic");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)isPlayingMusic);
			if (isPipebomb == null)
			{
				throw new Exception("Dingus.isPipebomb cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)isPipebomb).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)isPipebomb, "isPipebomb");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)isPipebomb);
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_Dingus()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(88404199u, new RpcReceiveHandler(__rpc_handler_88404199));
			NetworkManager.__rpc_func_table.Add(1120322383u, new RpcReceiveHandler(__rpc_handler_1120322383));
		}

		private static void __rpc_handler_88404199(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((Dingus)(object)target).EvilMaxwellServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1120322383(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Dingus)(object)target).EvilMaxwellClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "Dingus";
		}
	}
	public class Missile : NetworkBehaviour
	{
		public int damage = 50;

		public float maxDistance = 10f;

		public float minDistance;

		public float gravity = 2.4f;

		public float flightDelay = 0.5f;

		public float flightForce = 150f;

		public float flightTime = 2f;

		public float autoDestroyTime = 3f;

		private float timeAlive;

		public float LobForce = 100f;

		public ParticleSystem particleSystem;

		private void OnCollisionEnter(Collision collision)
		{
			if (((NetworkBehaviour)this).IsHost)
			{
				Boom();
				BoomClientRpc();
			}
			else
			{
				BoomServerRpc();
			}
		}

		private void Start()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).GetComponent<Rigidbody>().useGravity = false;
			if (((NetworkBehaviour)this).IsHost)
			{
				((Component)this).GetComponent<Rigidbody>().AddForce(((Component)this).transform.forward * LobForce, (ForceMode)1);
			}
		}

		[ClientRpc]
		public void BoomClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3331368301u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3331368301u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Boom();
				}
			}
		}

		[ServerRpc]
		public void BoomServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(452316787u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 452316787u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				Boom();
				BoomClientRpc();
			}
		}

		public void CreateExplosion()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB attacker = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => ((NetworkBehaviour)x).OwnerClientId == ((NetworkBehaviour)this).OwnerClientId));
			Utilities.CreateExplosion(((Component)this).transform.position, spawnExplosionEffect: true, damage, minDistance, maxDistance, 10, (CauseOfDeath)3, attacker);
		}

		public void Boom()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)particleSystem == (Object)null)
			{
				Debug.LogError((object)"No particle system set on missile, destruction time!!");
				CreateExplosion();
				if (((NetworkBehaviour)this).IsHost)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				return;
			}
			particleSystem.Stop(true, (ParticleSystemStopBehavior)1);
			((Component)particleSystem).transform.SetParent((Transform)null);
			((Component)particleSystem).transform.localScale = Vector3.one;
			GameObject gameObject = ((Component)particleSystem).gameObject;
			MainModule main = particleSystem.main;
			float duration = ((MainModule)(ref main)).duration;
			main = particleSystem.main;
			MinMaxCurve startLifetime = ((MainModule)(ref main)).startLifetime;
			Object.Destroy((Object)(object)gameObject, duration + ((MinMaxCurve)(ref startLifetime)).constant);
			CreateExplosion();
			if (((NetworkBehaviour)this).IsHost)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void FixedUpdate()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsHost)
			{
				return;
			}
			((Component)this).GetComponent<Rigidbody>().useGravity = false;
			((Component)this).GetComponent<Rigidbody>().AddForce(Vector3.down * gravity);
			if (timeAlive <= flightTime && timeAlive >= flightDelay)
			{
				((Component)this).GetComponent<Rigidbody>().AddForce(((Component)this).transform.forward * flightForce);
			}
			timeAlive += Time.fixedDeltaTime;
			if (timeAlive > autoDestroyTime)
			{
				if (((NetworkBehaviour)this).IsHost)
				{
					Boom();
					BoomClientRpc();
				}
				else
				{
					BoomServerRpc();
				}
			}
			else
			{
				Debug.Log((object)("Time alive: " + timeAlive + " / " + autoDestroyTime));
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_Missile()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3331368301u, new RpcReceiveHandler(__rpc_handler_3331368301));
			NetworkManager.__rpc_func_table.Add(452316787u, new RpcReceiveHandler(__rpc_handler_452316787));
		}

		private static void __rpc_handler_3331368301(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Missile)(object)target).BoomClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_452316787(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((Missile)(object)target).BoomServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "Missile";
		}
	}
	public class PouchyBelt : GrabbableObject
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetHoverTipAndCurrentInteractTrigger <0>__PlayerControllerB_SetHoverTipAndCurrentInteractTrigger;

			public static hook_BeginGrabObject <1>__PlayerControllerB_BeginGrabObject;
		}

		public Transform beltCosmetic;

		public Vector3 beltCosmeticPositionOffset = new Vector3(0f, 0f, 0f);

		public Vector3 beltCosmeticRotationOffset = new Vector3(0f, 0f, 0f);

		public int beltCapacity = 3;

		private PlayerControllerB previousPlayerHeldBy;

		public List<int> slotIndexes = new List<int>();

		public static void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__PlayerControllerB_SetHoverTipAndCurrentInteractTrigger;
			if (obj == null)
			{
				hook_SetHoverTipAndCurrentInteractTrigger val = PlayerControllerB_SetHoverTipAndCurrentInteractTrigger;
				<>O.<0>__PlayerControllerB_SetHoverTipAndCurrentInteractTrigger = val;
				obj = (object)val;
			}
			PlayerControllerB.SetHoverTipAndCurrentInteractTrigger += (hook_SetHoverTipAndCurrentInteractTrigger)obj;
			object obj2 = <>O.<1>__PlayerControllerB_BeginGrabObject;
			if (obj2 == null)
			{
				hook_BeginGrabObject val2 = PlayerControllerB_BeginGrabObject;
				<>O.<1>__PlayerControllerB_BeginGrabObject = val2;
				obj2 = (object)val2;
			}
			PlayerControllerB.BeginGrabObject += (hook_BeginGrabObject)obj2;
		}

		public void Awake()
		{
			if (InputCompat.Enabled)
			{
				InputCompat.LTUtilityBeltQuick1.started += InputReceived;
				InputCompat.LTUtilityBeltQuick2.started += InputReceived;
				InputCompat.LTUtilityBeltQuick3.started += InputReceived;
				InputCompat.LTUtilityBeltQuick4.started += InputReceived;
			}
		}

		private static void PlayerControllerB_BeginGrabObject(orig_BeginGrabObject orig, PlayerControllerB self)
		{
			//IL_000c: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			self.interactRay = new Ray(((Component)self.gameplayCamera).transform.position, ((Component)self.gameplayCamera).transform.forward);
			if (!Physics.Raycast(self.interactRay, ref self.hit, self.grabDistance, self.interactableObjectsMask) || ((Component)((RaycastHit)(ref self.hit)).collider).gameObject.layer == 8 || !(((Component)((RaycastHit)(ref self.hit)).collider).tag == "PhysicsProp") || self.twoHanded || self.sinkingValue > 0.73f)
			{
				return;
			}
			self.currentlyGrabbingObject = ((Component)((Component)((RaycastHit)(ref self.hit)).collider).transform).gameObject.GetComponent<GrabbableObject>();
			if ((!GameNetworkManager.Instance.gameHasStarted && !self.currentlyGrabbingObject.itemProperties.canBeGrabbedBeforeGameStart && ((Object)(object)StartOfRound.Instance.testRoom == (Object)null || !StartOfRound.Instance.testRoom.activeSelf)) || (Object)(object)self.currentlyGrabbingObject == (Object)null || self.inSpecialInteractAnimation || self.currentlyGrabbingObject.isHeld || self.currentlyGrabbingObject.isPocketed)
			{
				return;
			}
			NetworkObject networkObject = ((NetworkBehaviour)self.currentlyGrabbingObject).NetworkObject;
			if (!((Object)(object)networkObject == (Object)null) && networkObject.IsSpawned)
			{
				if (self.currentlyGrabbingObject is PouchyBelt && self.ItemSlots.Any((GrabbableObject x) => (Object)(object)x != (Object)null && x is PouchyBelt))
				{
					self.currentlyGrabbingObject.grabbable = false;
				}
				orig.Invoke(self);
				if (self.currentlyGrabbingObject is PouchyBelt)
				{
					self.currentlyGrabbingObject.grabbable = true;
				}
			}
		}

		private static void PlayerControllerB_SetHoverTipAndCurrentInteractTrigger(orig_SetHoverTipAndCurrentInteractTrigger orig, PlayerControllerB self)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			if (!Physics.Raycast(self.interactRay, ref self.hit, self.grabDistance, self.interactableObjectsMask) || ((Component)((RaycastHit)(ref self.hit)).collider).gameObject.layer == 8 || !(((Component)((RaycastHit)(ref self.hit)).collider).tag == "PhysicsProp"))
			{
				return;
			}
			if (self.FirstEmptyItemSlot() == -1)
			{
				((TMP_Text)self.cursorTip).text = "Inventory full!";
			}
			else if (((Component)((RaycastHit)(ref self.hit)).collider).gameObject.GetComponent<GrabbableObject>() is PouchyBelt)
			{
				if (self.ItemSlots.Any((GrabbableObject x) => (Object)(object)x != (Object)null && x is PouchyBelt))
				{
					((TMP_Text)self.cursorTip).text = "(Cannot hold more than 1 belt)";
				}
				else
				{
					((TMP_Text)self.cursorTip).text = "Pick up belt";
				}
			}
		}

		public void InputReceived(CallbackContext context)
		{
			if (((NetworkBehaviour)this).IsOwner && (Object)(object)base.playerHeldBy != (Object)null && ((CallbackContext)(ref context)).started)
			{
				int num = -1;
				if (((CallbackContext)(ref context)).action == InputCompat.LTUtilityBeltQuick1)
				{
					num = 0;
				}
				else if (((CallbackContext)(ref context)).action == InputCompat.LTUtilityBeltQuick2)
				{
					num = 1;
				}
				else if (((CallbackContext)(ref context)).action == InputCompat.LTUtilityBeltQuick3)
				{
					num = 2;
				}
				else if (((CallbackContext)(ref context)).action == InputCompat.LTUtilityBeltQuick4)
				{
					num = 3;
				}
				if (num != -1 && num < slotIndexes.Count)
				{
					base.playerHeldBy.SwitchItemSlots(slotIndexes[num]);
					Plugin.logger.LogInfo((object)$"Switched to slot: {slotIndexes[num]}");
				}
			}
		}

		public override void LateUpdate()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).LateUpdate();
			if ((Object)(object)previousPlayerHeldBy != (Object)null)
			{
				((Component)beltCosmetic).gameObject.SetActive(true);
				beltCosmetic.SetParent((Transform)null);
				((Renderer)((Component)beltCosmetic).GetComponent<MeshRenderer>()).enabled = true;
				if (((NetworkBehaviour)this).IsOwner)
				{
					((Renderer)((Component)beltCosmetic).GetComponent<MeshRenderer>()).enabled = false;
				}
				Transform parent = previousPlayerHeldBy.lowerSpine.parent;
				beltCosmetic.position = parent.position + beltCosmeticPositionOffset;
				Quaternion rotation = parent.rotation;
				Quaternion rotation2 = Quaternion.Euler(((Quaternion)(ref rotation)).eulerAngles + beltCosmeticRotationOffset);
				beltCosmetic.rotation = rotation2;
				((Renderer)base.mainObjectRenderer).enabled = false;
				((Component)this).gameObject.SetActive(true);
			}
			else
			{
				((Component)beltCosmetic).gameObject.SetActive(false);
				((Renderer)base.mainObjectRenderer).enabled = true;
				beltCosmetic.SetParent(((Component)this).transform);
			}
		}

		public void UpdateHUD(bool add)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			slotIndexes.Clear();
			HUDManager instance = HUDManager.Instance;
			if (add)
			{
				int num = 0;
				GrabbableObject[] itemSlots = GameNetworkManager.Instance.localPlayerController.ItemSlots;
				for (int i = 0; i < itemSlots.Length; i++)
				{
					if (itemSlots[i] is PouchyBelt)
					{
						num++;
					}
				}
				Image val = instance.itemSlotIconFrames[0];
				Image val2 = instance.itemSlotIcons[0];
				int num2 = instance.itemSlotIconFrames.Length;
				((Component)val).GetComponentInParent<CanvasScaler>();
				((Component)val).GetComponentInParent<AspectRatioFitter>();
				float x2 = ((Graphic)val).rectTransform.sizeDelta.x;
				float y = ((Graphic)val).rectTransform.sizeDelta.y;
				float num3 = ((Graphic)val).rectTransform.anchoredPosition.y + 1.125f * y * (float)num;
				Vector3 localEulerAngles = ((Transform)((Graphic)val).rectTransform).localEulerAngles;
				Vector3 localEulerAngles2 = ((Transform)((Graphic)val2).rectTransform).localEulerAngles;
				List<Image> list = instance.itemSlotIconFrames.ToList();
				List<Image> list2 = instance.itemSlotIcons.ToList();
				int num4 = list.FindLastIndex((Image x) => Regex.IsMatch(((Object)((Component)x).gameObject).name.ToLowerInvariant(), "\\bslot\\d\\b"));
				_ = beltCapacity;
				_ = beltCapacity;
				Debug.Log((object)$"Adding {beltCapacity} item slots! Surely this will go well..");
				Debug.Log((object)$"Adding after index: {num4}");
				for (int j = 0; j < beltCapacity; j++)
				{
					float num5 = 0f - ((Component)((Transform)((Graphic)val).rectTransform).parent).GetComponent<RectTransform>().sizeDelta.x / 2f - 3f + (float)j * x2 + (float)j * 15f;
					Image val3 = Object.Instantiate<Image>(list[0], ((Component)val).transform.parent);
					((Object)val3).name = $"Slot{num2 + j}[LethalThingsBelt]";
					((Graphic)val3).rectTransform.anchoredPosition = new Vector2(num5, num3);
					((Transform)((Graphic)val3).rectTransform).eulerAngles = localEulerAngles;
					Image component = ((Component)((Component)val3).transform.GetChild(0)).GetComponent<Image>();
					((Object)component).name = "icon";
					((Behaviour)component).enabled = false;
					((Transform)((Graphic)component).rectTransform).eulerAngles = localEulerAngles2;
					((Transform)((Graphic)component).rectTransform).Rotate(new Vector3(0f, 0f, -90f));
					int num6 = num4 + j + 1;
					list.Insert(num6, val3);
					list2.Insert(num6, component);
					slotIndexes.Add(num6);
					((Component)val3).transform.SetSiblingIndex(num6);
				}
				instance.itemSlotIconFrames = list.ToArray();
				instance.itemSlotIcons = list2.ToArray();
				Debug.Log((object)$"Added {beltCapacity} item slots!");
				return;
			}
			List<Image> list3 = instance.itemSlotIconFrames.ToList();
			List<Image> list4 = instance.itemSlotIcons.ToList();
			int count = list3.Count;
			int num7 = 0;
			for (int num8 = count - 1; num8 >= 0; num8--)
			{
				if (((Object)list3[num8]).name.Contains("[LethalThingsBelt]"))
				{
					num7++;
					Image obj = list3[num8];
					list3.RemoveAt(num8);
					list4.RemoveAt(num8);
					Object.Destroy((Object)(object)((Component)obj).gameObject);
					if (num7 >= beltCapacity)
					{
						break;
					}
				}
			}
			instance.itemSlotIconFrames = list3.ToArray();
			instance.itemSlotIcons = list4.ToArray();
			Debug.Log((object)$"Removed {beltCapacity} item slots!");
		}

		public void AddItemSlots()
		{
			if ((Object)(object)base.playerHeldBy != (Object)null)
			{
				List<GrabbableObject> list = base.playerHeldBy.ItemSlots.ToList();
				base.playerHeldBy.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[list.Count + beltCapacity];
				for (int i = 0; i < list.Count; i++)
				{
					base.playerHeldBy.ItemSlots[i] = list[i];
				}
				if ((Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					UpdateHUD(add: true);
				}
			}
		}

		public void RemoveItemSlots()
		{
			if (!((Object)(object)base.playerHeldBy != (Object)null))
			{
				return;
			}
			int num = base.playerHeldBy.ItemSlots.Length - beltCapacity;
			int currentItemSlot = base.playerHeldBy.currentItemSlot;
			for (int i = 0; i < beltCapacity; i++)
			{
				GrabbableObject val = base.playerHeldBy.ItemSlots[num + i];
				if ((Object)(object)val != (Object)null)
				{
					base.playerHeldBy.DropItem(val, num + i);
				}
			}
			int currentItemSlot2 = base.playerHeldBy.currentItemSlot;
			currentItemSlot2 = ((currentItemSlot < base.playerHeldBy.ItemSlots.Length) ? currentItemSlot : 0);
			List<GrabbableObject> list = base.playerHeldBy.ItemSlots.ToList();
			base.playerHeldBy.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[list.Count - beltCapacity];
			for (int j = 0; j < base.playerHeldBy.ItemSlots.Length; j++)
			{
				base.playerHeldBy.ItemSlots[j] = list[j];
			}
			if ((Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				UpdateHUD(add: false);
			}
			base.playerHeldBy.SwitchItemSlots(currentItemSlot2);
		}

		public override void DiscardItem()
		{
			RemoveItemSlots();
			previousPlayerHeldBy = null;
			((GrabbableObject)this).DiscardItem();
		}

		public override void OnNetworkDespawn()
		{
			RemoveItemSlots();
			previousPlayerHeldBy = null;
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		public void GrabItemOnClient()
		{
			((GrabbableObject)this).GrabItemOnClient();
		}

		public override void OnDestroy()
		{
			if (InputCompat.Enabled)
			{
				InputCompat.LTUtilityBeltQuick1.started -= InputReceived;
				InputCompat.LTUtilityBeltQuick2.started -= InputReceived;
				InputCompat.LTUtilityBeltQuick3.started -= InputReceived;
				InputCompat.LTUtilityBeltQuick4.started -= InputReceived;
			}
			((NetworkBehaviour)this).OnDestroy();
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			if ((Object)(object)base.playerHeldBy != (Object)null)
			{
				if ((Object)(object)base.playerHeldBy != (Object)(object)previousPlayerHeldBy)
				{
					AddItemSlots();
				}
				previousPlayerHeldBy = base.playerHeldBy;
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "PouchyBelt";
		}
	}
	public class PowerOutletStun : NetworkBehaviour
	{
		private Coroutine electrocutionCoroutine;

		public AudioSource strikeAudio;

		public ParticleSystem strikeParticle;

		private NetworkVariable<int> damage = new NetworkVariable<int>(20, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public void Electrocute(ItemCharger socket)
		{
			Debug.Log((object)"Attempting electrocution");
			if (electrocutionCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(electrocutionCoroutine);
			}
			electrocutionCoroutine = ((MonoBehaviour)this).StartCoroutine(electrocutionDelayed(socket));
		}

		public void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			StormyWeather val = Object.FindObjectOfType<StormyWeather>(true);
			GameObject gameObject = ((Component)val.targetedStrikeAudio).gameObject;
			strikeAudio = Object.Instantiate<GameObject>(gameObject, ((Component)this).transform).GetComponent<AudioSource>();
			((Component)strikeAudio).transform.localPosition = Vector3.zero;
			((Component)strikeAudio).gameObject.SetActive(true);
			strikeParticle = Object.Instantiate<GameObject>(((Component)val.explosionEffectParticle).gameObject, ((Component)this).transform).GetComponent<ParticleSystem>();
			((Component)strikeParticle).transform.localPosition = Vector3.zero;
			((Component)strikeParticle).gameObject.SetActive(true);
			if (((NetworkBehaviour)this).IsHost)
			{
				damage.Value = Config.itemChargerElectrocutionDamage.Value;
			}
		}

		private IEnumerator electrocutionDelayed(ItemCharger socket)
		{
			Debug.Log((object)"Electrocution started");
			socket.zapAudio.Play();
			yield return (object)new WaitForSeconds(0.75f);
			socket.chargeStationAnimator.SetTrigger("zap");
			Debug.Log((object)"Electrocution finished");
			if (((NetworkBehaviour)this).NetworkObject.IsOwner && !((NetworkBehaviour)this).NetworkObject.IsOwnedByServer)
			{
				Debug.Log((object)"Sending stun to server!!");
				ElectrocutedServerRpc(((Component)this).transform.position);
			}
			else if (((NetworkBehaviour)this).NetworkObject.IsOwner && ((NetworkBehaviour)this).NetworkObject.IsOwnedByServer)
			{
				Debug.Log((object)"Sending stun to clients!!");
				ElectrocutedClientRpc(((Component)this).transform.position);
				Electrocuted(((Component)this).transform.position);
			}
		}

		[ClientRpc]
		private void ElectrocutedClientRpc(Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(328188188u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref position);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 328188188u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Debug.Log((object)"Stun received!!");
					Electrocuted(position);
				}
			}
		}

		private void Electrocuted(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			StormyWeather obj = Object.FindObjectOfType<StormyWeather>(true);
			Utilities.CreateExplosion(position, spawnExplosionEffect: false, Config.itemChargerElectrocutionDamage.Value, 0f, 5f, 3, (CauseOfDeath)11);
			strikeParticle.Play();
			obj.PlayThunderEffects(position, strikeAudio);
		}

		[ServerRpc]
		private void ElectrocutedServerRpc(Vector3 position)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Invalid comparison between Unknown and I4
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2844681185u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref position);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2844681185u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ElectrocutedClientRpc(position);
			}
		}

		protected override void __initializeVariables()
		{
			if (damage == null)
			{
				throw new Exception("PowerOutletStun.damage cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)damage).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)damage, "damage");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)damage);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_PowerOutletStun()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(328188188u, new RpcReceiveHandler(__rpc_handler_328188188));
			NetworkManager.__rpc_func_table.Add(2844681185u, new RpcReceiveHandler(__rpc_handler_2844681185));
		}

		private static void __rpc_handler_328188188(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 position = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((PowerOutletStun)(object)target).ElectrocutedClientRpc(position);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2844681185(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				Vector3 position = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((PowerOutletStun)(object)target).ElectrocutedServerRpc(position);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "PowerOutletStun";
		}
	}
	public class ProjectileWeapon : SaveableObject
	{
		public AudioSource mainAudio;

		public AudioClip[] activateClips;

		public AudioClip[] noAmmoSounds;

		public AudioClip[] reloadSounds;

		public Transform aimDirection;

		public int maxAmmo = 4;

		private NetworkVariable<int> currentAmmo = new NetworkVariable<int>(4, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public GameObject projectilePrefab;

		public float LobForce = 100f;

		private float timeSinceLastShot;

		private PlayerControllerB previousPlayerHeldBy;

		public Animator Animator;

		public ParticleSystem particleSystem;

		public Item ammoItem;

		public int ammoSlotToUse = -1;

		public override void SaveObjectData()
		{
			SaveData.SaveObjectData("projectileWeaponAmmoData", currentAmmo.Value, uniqueId);
		}

		public override void LoadObjectData()
		{
			if (((NetworkBehaviour)this).IsHost)
			{
				currentAmmo.Value = SaveData.LoadObjectData<int>("projectileWeaponAmmoData", uniqueId);
			}
		}

		public static void Init()
		{
		}

		private static bool GrabbableObject_UseItemBatteries(orig_UseItemBatteries orig, GrabbableObject self)
		{
			if (self is ProjectileWeapon)
			{
				return true;
			}
			return orig.Invoke(self);
		}

		public override void Start()
		{
			((GrabbableObject)this).Start();
		}

		public override void OnDestroy()
		{
			((NetworkBehaviour)this).OnDestroy();
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			if (((NetworkBehaviour)this).IsServer)
			{
				currentAmmo.Value = maxAmmo;
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (currentAmmo.Value > 0)
			{
				if (((NetworkBehaviour)this).IsHost)
				{
					NetworkVariable<int> obj = currentAmmo;
					int value = obj.Value;
					obj.Value = value - 1;
				}
				PlayRandomAudio(mainAudio, activateClips);
				Animator.Play("fire");
				particleSystem.Play();
				timeSinceLastShot = 0f;
				if (((NetworkBehaviour)this).IsOwner)
				{
					if (((NetworkBehaviour)this).IsHost)
					{
						ProjectileSpawner(aimDirection.position, aimDirection.rotation);
					}
					else
					{
						SpawnProjectileServerRpc(aimDirection.position, aimDirection.rotation);
					}
				}
			}
			else
			{
				PlayRandomAudio(mainAudio, noAmmoSounds);
			}
		}

		private bool ReloadedGun()
		{
			int num = FindAmmoInInventory();
			if (num == -1)
			{
				return false;
			}
			ammoSlotToUse = num;
			return true;
		}

		private int FindAmmoInInventory()
		{
			for (int i = 0; i < ((GrabbableObject)this).playerHeldBy.ItemSlots.Length; i++)
			{
				if (!((Object)(object)((GrabbableObject)this).playerHeldBy.ItemSlots[i] == (Object)null) && ((GrabbableObject)this).playerHeldBy.ItemSlots[i].itemProperties.itemId == ammoItem.itemId)
				{
					return i;
				}
			}
			return -1;
		}

		[ServerRpc]
		private void FixWeightServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(43845628u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 43845628u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				FixWeightClientRpc();
			}
		}

		[ClientRpc]
		private void FixWeightClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(948021082u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 948021082u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && (Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
				{
					PlayerControllerB playerHeldBy = ((GrabbableObject)this).playerHeldBy;
					playerHeldBy.carryWeight -= Mathf.Clamp(ammoItem.weight - 1f, 0f, 10f);
				}
			}
		}

		public override void ItemInteractLeftRight(bool right)
		{
			((GrabbableObject)this).ItemInteractLeftRight(right);
			if (right || !((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			if (ReloadedGun())
			{
				if (currentAmmo.Value > 0)
				{
					HUDManager.Instance.DisplayTip("Item already loaded.", "You can reload once you use up all the ammo.", false, false, "LC_Tip1");
					return;
				}
				ReloadAmmoServerRpc();
				DestroyItemInSlotAndSync(ammoSlotToUse);
				ammoSlotToUse = -1;
			}
			else
			{
				HUDManager.Instance.DisplayTip("No ammo found.", "Buy " + ammoItem.itemName + " from the Terminal to reload.", false, false, "LC_Tip1");
			}
		}

		[ServerRpc]
		private void ReloadAmmoServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1064596822u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1064596822u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				currentAmmo.Value = maxAmmo;
				ReloadAmmoSoundClientRpc();
			}
		}

		[ClientRpc]
		private void ReloadAmmoSoundClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3520251861u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3520251861u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlayRandomAudio(mainAudio, reloadSounds);
					Animator.Play("reload");
				}
			}
		}

		[ServerRpc]
		private void SpawnProjectileServerRpc(Vector3 aimPosition, Quaternion aimRotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Invalid comparison between Unknown and I4
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(681922146u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref aimPosition);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref aimRotation);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 681922146u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ProjectileSpawner(aimPosition, aimRotation);
			}
		}

		private void ProjectileSpawner(Vector3 aimPosition, Quaternion aimRotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(projectilePrefab, aimPosition, aimRotation);
			obj.GetComponent<NetworkObject>().SpawnWithOwnership(((NetworkBehaviour)this).OwnerClientId, false);
			obj.GetComponent<Rigidbody>().AddForce(aimDirection.forward * LobForce, (ForceMode)1);
		}

		private void PlayRandomAudio(AudioSource audioSource, AudioClip[] audioClips)
		{
			if (audioClips.Length != 0)
			{
				audioSource.PlayOneShot(audioClips[Random.Range(0, audioClips.Length)]);
			}
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
			timeSinceLastShot += Time.deltaTime;
		}

		private void OnEnable()
		{
		}

		private void OnDisable()
		{
		}

		public override void PocketItem()
		{
			((GrabbableObject)this).PocketItem();
			if ((Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
			{
				((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = false;
			}
		}

		public override void DiscardItem()
		{
			((GrabbableObject)this).DiscardItem();
			if ((Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
			{
				((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = false;
			}
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = true;
		}

		public void DestroyItemInSlotAndSync(int itemSlot)
		{
			if (((NetworkBehaviour)this).IsOwner)
			{
				if (itemSlot >= ((GrabbableObject)this).playerHeldBy.ItemSlots.Length || (Object)(object)((GrabbableObject)this).playerHeldBy.ItemSlots[itemSlot] == (Object)null)
				{
					Debug.LogError((object)$"Destroy item in slot called for a slot (slot {itemSlot}) which is empty or incorrect");
				}
				DestroyItemInSlotServerRpc(itemSlot);
			}
		}

		[ServerRpc]
		public void DestroyItemInSlotServerRpc(int itemSlot)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3656085789u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, itemSlot);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3656085789u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				DestroyItemInSlotClientRpc(itemSlot);
			}
		}

		[ClientRpc]
		public void DestroyItemInSlotClientRpc(int itemSlot)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(314723133u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, itemSlot);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 314723133u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					DestroyItemInSlot(itemSlot);
				}
			}
		}

		public void DestroyItemInSlot(int itemSlot)
		{
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || NetworkManager.Singleton.ShutdownInProgress)
			{
				return;
			}
			GrabbableObject val = ((GrabbableObject)this).playerHeldBy.ItemSlots[itemSlot];
			if ((Object)(object)val == (Object)null || (Object)(object)val.itemProperties == (Object)null)
			{
				Plugin.logger.LogError((object)"Item properties are null, cannot destroy item in slot");
				return;
			}
			PlayerControllerB playerHeldBy = ((GrabbableObject)this).playerHeldBy;
			playerHeldBy.carryWeight -= Mathf.Clamp(val.itemProperties.weight - 1f, 0f, 10f);
			if (((GrabbableObject)this).playerHeldBy.currentItemSlot == itemSlot)
			{
				((GrabbableObject)this).playerHeldBy.isHoldingObject = false;
				((GrabbableObject)this).playerHeldBy.twoHanded = false;
				if (((NetworkBehaviour)((GrabbableObject)this).playerHeldBy).IsOwner)
				{
					((GrabbableObject)this).playerHeldBy.playerBodyAnimator.SetBool("cancelHolding", true);
					((GrabbableObject)this).playerHeldBy.playerBod

BepInEx/plugins/mask-the-dead/MaskTheDead.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using MaskTheDead.Components;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
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("MaskTheDead")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("If a dead body is next to a mask there's a chance that the body is possesed")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("MaskTheDead")]
[assembly: AssemblyTitle("MaskTheDead")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MaskTheDead
{
	public class Configuration
	{
		private ConfigEntry<float> configPossessionChance;

		private ConfigEntry<int> configRetryPossesionTime;

		private ConfigEntry<int> configMaskPossessionRange;

		private ConfigFile File;

		public float PossesionChance => configPossessionChance.Value;

		public int RetryPossesionTime => configRetryPossesionTime.Value;

		public int MaskPossessionRange => configMaskPossessionRange.Value;

		public int RetryPossesionMinTime => 10000;

		public Configuration(ConfigFile config)
		{
			File = config;
			configPossessionChance = File.Bind<float>("General", "PossessionChance", 1f, "A number between 0 and 1 (included) representing the percentage of a body being possessed by a nearby mask");
			configRetryPossesionTime = File.Bind<int>("General", "RetryPossesionTime", RetryPossesionMinTime, $"Time in milliseconds after which a mask will attempt to posses a nearby body again, less than {RetryPossesionMinTime} milliseconds is ignored");
			configMaskPossessionRange = File.Bind<int>("General", "MaskPossessionRange", 10, "Range, in units, of the mask repossession trigger. Only bodies close enough will be considered for repossessions!");
		}
	}
	[BepInPlugin("MaskTheDead", "MaskTheDead", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource TheLogger;

		public static Configuration TheConfiguration;

		public Plugin()
		{
			TheConfiguration = new Configuration(((BaseUnityPlugin)this).Config);
		}

		private void Awake()
		{
			TheLogger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MaskTheDead is loaded!");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MaskTheDead";

		public const string PLUGIN_NAME = "MaskTheDead";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace MaskTheDead.Patchers
{
	[HarmonyPatch]
	public class GrabbableObjectMaskPatcher
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		private static bool StartPatch(ref GrabbableObject __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				Plugin.TheLogger.LogFatal((object)"This instance is null, cannot patch item");
				return true;
			}
			GrabbableObject obj = __instance;
			HauntedMaskItem val = (HauntedMaskItem)(object)((obj is HauntedMaskItem) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (!GameNetworkManager.Instance.isHostingGame)
			{
				Plugin.TheLogger.LogInfo((object)"Avoding patch for non hosts");
				return true;
			}
			Plugin.TheLogger.LogInfo((object)"Adding mask watcher to haunted mask!");
			((Component)val).gameObject.AddComponent<MaskTheDeadComponent>();
			return true;
		}
	}
}
namespace MaskTheDead.Components
{
	public class MaskTheDeadComponent : NetworkBehaviour
	{
		private readonly Dictionary<GameObject, Coroutine> _NearbyBodies = new Dictionary<GameObject, Coroutine>();

		private HauntedMaskItem _MaskComponent;

		private SphereCollider _Collider;

		public bool PossessionChancePassed => Random.value < Plugin.TheConfiguration.PossesionChance;

		public bool CanRetryPossession => Plugin.TheConfiguration.RetryPossesionTime >= Plugin.TheConfiguration.RetryPossesionMinTime;

		private bool CanComponentUseRagdoll(RagdollGrabbableObject ragdoll)
		{
			if (((GrabbableObject)ragdoll).isHeld || ((GrabbableObject)ragdoll).isHeldByEnemy)
			{
				Plugin.TheLogger.LogInfo((object)"Cant attempt possession of held ragdoll...");
				return false;
			}
			if (((GrabbableObject)ragdoll).isInShipRoom)
			{
				Plugin.TheLogger.LogInfo((object)"Cant attempt possession of body in ship");
				return false;
			}
			return true;
		}

		private void Awake()
		{
			_MaskComponent = ((Component)this).gameObject.GetComponent<HauntedMaskItem>();
			_Collider = ((Component)this).gameObject.AddComponent<SphereCollider>();
			_Collider.radius = Plugin.TheConfiguration.MaskPossessionRange;
			((Collider)_Collider).isTrigger = true;
		}

		private void Update()
		{
			if ((Object)(object)_MaskComponent == (Object)null || (Object)(object)_Collider == (Object)null)
			{
				Plugin.TheLogger.LogWarning((object)"Mask or collider is null, deleting component!");
				((NetworkBehaviour)this).NetworkObject.Despawn(true);
				Object.Destroy((Object)(object)this);
			}
			else if (((GrabbableObject)_MaskComponent).isHeldByEnemy || ((GrabbableObject)_MaskComponent).isHeld)
			{
				((Collider)_Collider).enabled = false;
				CleanupCoroutines();
			}
			else
			{
				((Collider)_Collider).enabled = true;
			}
		}

		public override void OnDestroy()
		{
			Plugin.TheLogger.LogInfo((object)"Destroying repossession component!");
			CleanupCoroutines();
			((NetworkBehaviour)this).OnDestroy();
		}

		public override void OnNetworkDespawn()
		{
			Plugin.TheLogger.LogInfo((object)"Network despawn, clearning repossession component!");
			((NetworkBehaviour)this).OnNetworkDespawn();
			CleanupCoroutines();
		}

		private void OnTriggerEnter(Collider other)
		{
			RagdollGrabbableObject colliderRagdoll = GetColliderRagdoll(other);
			if ((Object)(object)colliderRagdoll == (Object)null)
			{
				Plugin.TheLogger.LogInfo((object)"Object in mask range is not ragdoll");
			}
			else if (CanComponentUseRagdoll(colliderRagdoll) && !_NearbyBodies.ContainsKey(((Component)colliderRagdoll).gameObject))
			{
				_NearbyBodies.Add(((Component)colliderRagdoll).gameObject, null);
				AttemptPossesion(colliderRagdoll);
			}
		}

		private void OnTriggerExit(Collider other)
		{
			Plugin.TheLogger.LogInfo((object)$"Something is leaving the mask range, i have {_NearbyBodies.Count} body nearby!");
			RagdollGrabbableObject colliderRagdoll = GetColliderRagdoll(other);
			Coroutine value;
			if ((Object)(object)colliderRagdoll == (Object)null)
			{
				Plugin.TheLogger.LogInfo((object)"The collider leaving is not of a ragdoll");
			}
			else if (_NearbyBodies.TryGetValue(((Component)colliderRagdoll).gameObject, out value))
			{
				if (value != null)
				{
					Plugin.TheLogger.LogInfo((object)"Stopping coroutine for body leaving mask range");
					((MonoBehaviour)this).StopCoroutine(value);
				}
				_NearbyBodies.Remove(((Component)colliderRagdoll).gameObject);
			}
			else
			{
				Plugin.TheLogger.LogWarning((object)"Body leaving mask range was not in dicitonary of bodies!");
			}
		}

		private RagdollGrabbableObject GetColliderRagdoll(Collider other)
		{
			RagdollGrabbableObject component = ((Component)other).gameObject.GetComponent<RagdollGrabbableObject>();
			Plugin.TheLogger.LogInfo((object)$"Collided with {((Component)other).gameObject}");
			if ((Object)(object)component != (Object)null && component.bodyID.Value >= 0)
			{
				Plugin.TheLogger.LogInfo((object)"Found ragdoll, lucky!");
				return component;
			}
			if (!((Object)other).name.Contains(".L") && !((Object)other).name.Contains(".R"))
			{
				Plugin.TheLogger.LogInfo((object)"This is not a bone!");
				return null;
			}
			Plugin.TheLogger.LogInfo((object)"Collided with a bone of a character, finding ragdoll on parents");
			return ((Component)other).gameObject.GetComponentInParent<RagdollGrabbableObject>();
		}

		private IEnumerator RepossessionCoroutine(object o)
		{
			yield return (object)new WaitForSeconds((float)(Plugin.TheConfiguration.RetryPossesionTime / 1000));
			yield return (object)new WaitForEndOfFrame();
			RagdollGrabbableObject val = (RagdollGrabbableObject)((o is RagdollGrabbableObject) ? o : null);
			if ((Object)(object)val != (Object)null && _NearbyBodies.TryGetValue(((Component)val).gameObject, out var _))
			{
				Plugin.TheLogger.LogInfo((object)"Ragdoll timer elapsed, attempting possession!");
				_NearbyBodies[((Component)val).gameObject] = null;
				AttemptPossesion(val);
			}
			else
			{
				Plugin.TheLogger.LogWarning((object)"Ragdoll was deleted, stopping repossession retry!");
			}
		}

		private void CleanupCoroutines()
		{
			if (_NearbyBodies.Count == 0)
			{
				return;
			}
			Plugin.TheLogger.LogInfo((object)"Cleaning up all nearby bodies!");
			foreach (KeyValuePair<GameObject, Coroutine> nearbyBody in _NearbyBodies)
			{
				if (nearbyBody.Value != null)
				{
					((MonoBehaviour)this).StopCoroutine(nearbyBody.Value);
				}
			}
			_NearbyBodies.Clear();
		}

		private void AttemptPossesion(RagdollGrabbableObject ragdoll)
		{
			if (!PossessionChancePassed)
			{
				Plugin.TheLogger.LogInfo((object)"Chance failed, will not possess body");
				if (CanRetryPossession)
				{
					Plugin.TheLogger.LogInfo((object)"Starting coroutine for repossession");
					if (_NearbyBodies[((Component)ragdoll).gameObject] != null)
					{
						((MonoBehaviour)this).StopCoroutine(_NearbyBodies[((Component)ragdoll).gameObject]);
					}
					Coroutine value = ((MonoBehaviour)this).StartCoroutine("RepossessionCoroutine", (object)ragdoll);
					_NearbyBodies[((Component)ragdoll).gameObject] = value;
				}
			}
			else
			{
				Plugin.TheLogger.LogInfo((object)"Chance for possession OK");
				BeginPossession(ragdoll);
			}
		}

		private void BeginPossession(RagdollGrabbableObject ragdoll)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Plugin.TheLogger.LogInfo((object)"!!POSSESSING DEAD BODY!!");
			HauntedMaskItem component = ((Component)this).gameObject.GetComponent<HauntedMaskItem>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.TheLogger.LogFatal((object)"Could not find mask item component, aborting possession!");
				return;
			}
			Plugin.TheLogger.LogInfo((object)"Spawning mimic");
			if ((Object)(object)ragdoll.ragdoll.playerScript == (Object)null)
			{
				Plugin.TheLogger.LogFatal((object)"Ragdoll's player script is null, aborting mimic spawn!");
				return;
			}
			((NetworkBehaviour)component).NetworkObject.RemoveOwnership();
			((NetworkBehaviour)ragdoll).NetworkObject.RemoveOwnership();
			SetPreviouslyHeldByOf(component, ragdoll.ragdoll.playerScript);
			component.CreateMimicServerRpc(((GrabbableObject)ragdoll).isInFactory, ((Component)ragdoll.ragdoll).transform.position);
			((NetworkBehaviour)component).NetworkObject.Despawn(true);
			Object.Destroy((Object)(object)component);
			Object.Destroy((Object)(object)((Component)((GrabbableObject)component).radarIcon).gameObject);
			((NetworkBehaviour)ragdoll).NetworkObject.Despawn(true);
			Object.Destroy((Object)(object)ragdoll);
		}

		private void SetPreviouslyHeldByOf(HauntedMaskItem item, PlayerControllerB c)
		{
			((object)item).GetType().GetField("previousPlayerHeldBy", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(item, c);
			Plugin.TheLogger.LogInfo((object)"Set private field previousPlayerHeldBy");
		}
	}
}

BepInEx/plugins/TooManyEmotes.dll

Decompiled 8 months 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.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Dissonance.Integrations.Unity_NFGO;
using GameNetcodeStuff;
using HarmonyLib;
using MoreCompany.Cosmetics;
using TMPro;
using TooManyEmotes.Config;
using TooManyEmotes.Networking;
using TooManyEmotes.Patches;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEngine.EventSystems;
using UnityEngine.Experimental.Rendering;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TooManyEmotes")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TooManyEmotes")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d6950625-e3a1-4896-a183-87110491bf18")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TooManyEmotes
{
	[HarmonyPatch]
	public static class EmoteMenuManager
	{
		public static GameObject menuGameObject;

		public static RectTransform menuTransform;

		public static CanvasGroup canvasGroup;

		public static RawImage renderTextureImageUI;

		public static TextMeshPro swapPageText;

		public static TextMeshPro currentEmoteText;

		public static RenderTexture renderTexture;

		public static Camera renderingCamera;

		public static GameObject previewPlayerObject;

		public static SkinnedMeshRenderer previewPlayerMesh;

		public static Animator previewPlayerAnimator;

		public static AnimatorOverrideController previewPlayerAnimatorController;

		public static int playerLayer = LayerMask.NameToLayer("Player");

		public static float hoveredAlpha = 0.75f;

		public static float unhoveredAlpha = 0.75f;

		public static Color defaultUIColor = new Color(0.3f, 0.3f, 0.3f);

		public static List<EmoteUIElement> emoteUIElementsList;

		public static int hoveredEmoteUIIndex = -1;

		public static int currentPage = 0;

		public static List<EmoteLoadoutUIElement> emoteLoadoutUIElementsList;

		public static List<List<UnlockableEmote>> emoteLoadouts;

		public static Color selectedLoadoutUIColor = new Color(0.2f, 0.2f, 1f);

		public static int currentLoadoutIndex = -1;

		public static int numLoadouts = 3;

		public static int hoveredLoadoutUIIndex = -1;

		public static QuickMenuManager quickMenuManager => StartOfRound.Instance?.localPlayerController?.quickMenuManager;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static int playerLayerMask => 1 << playerLayer;

		public static int hoveredEmoteIndex => (hoveredEmoteUIIndex >= 0) ? (hoveredEmoteUIIndex + 8 * currentPage) : (-1);

		public static int numPages => Mathf.Max((currentLoadoutEmotesList.Count - 1) / emoteUIElementsList.Count, 0) + 1;

		public static UnlockableEmote previewingEmote => (hoveredEmoteIndex >= 0 && hoveredEmoteIndex < currentLoadoutEmotesList.Count) ? currentLoadoutEmotesList[hoveredEmoteIndex] : null;

		public static List<UnlockableEmote> currentLoadoutEmotesList => emoteLoadouts[currentLoadoutIndex];

		public static bool isMenuOpen => menuGameObject.activeSelf;

		[HarmonyPatch(typeof(HUDManager), "Start")]
		[HarmonyPostfix]
		public static void InitializeUI(HUDManager __instance)
		{
			if (!((Object)(object)Plugin.radialMenuPrefab == (Object)null))
			{
				menuGameObject = Object.Instantiate<GameObject>(Plugin.radialMenuPrefab, __instance.HUDContainer.transform.parent);
				menuGameObject.transform.SetAsLastSibling();
				((Object)menuGameObject).name = "EmotesRadialMenu";
				menuTransform = menuGameObject.GetComponent<RectTransform>();
				renderTextureImageUI = menuGameObject.GetComponentInChildren<RawImage>();
				Transform transform = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialElements")).transform;
				swapPageText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/SwapPageText")).GetComponent<TextMeshPro>();
				currentEmoteText = ((Component)((Transform)menuTransform).Find("RadialMenuUI/RadialBase/CurrentEmoteText")).GetComponent<TextMeshPro>();
				((TMP_Text)currentEmoteText).text = "";
				emoteUIElementsList = new List<EmoteUIElement>();
				currentPage = 0;
				hoveredEmoteUIIndex = -1;
				for (int i = 0; i < transform.childCount; i++)
				{
					Transform child = transform.GetChild(i);
					EmoteUIElement item = new EmoteUIElement
					{
						uiGameObject = ((Component)child).gameObject,
						id = i,
						backgroundImage = ((Component)child).GetComponentInChildren<Image>(),
						textContainer = ((Component)child).GetComponentInChildren<TextMeshPro>()
					};
					emoteUIElementsList.Add(item);
				}
				EmoteLoadoutUIElement.uiCount = 0;
				Transform transform2 = ((Component)((Transform)menuTransform).Find("RadialMenuUI/EmoteLoadouts")).transform;
				((Component)transform2).gameObject.AddComponent<EmoteLoadoutUIContainer>();
				emoteLoadoutUIElementsList = new List<EmoteLoadoutUIElement>();
				emoteLoadoutUIElementsList.Add(((Component)transform2.GetChild(0)).gameObject.AddComponent<EmoteLoadoutUIElement>());
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				emoteLoadoutUIElementsList.Add(Object.Instantiate<EmoteLoadoutUIElement>(emoteLoadoutUIElementsList[0], transform2));
				for (int j = 0; j < emoteLoadoutUIElementsList.Count; j++)
				{
					((Object)emoteLoadoutUIElementsList[j]).name = "EmoteLoadout_" + j;
				}
				emoteLoadoutUIElementsList[0].loadoutName = "Favorites";
				emoteLoadoutUIElementsList[1].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[3]}>Legendary</color>";
				emoteLoadoutUIElementsList[2].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[2]}>Rare</color>";
				emoteLoadoutUIElementsList[3].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[1]}>Uncommon</color>";
				emoteLoadoutUIElementsList[4].loadoutName = $"<color={UnlockableEmote.rarityColorCodes[0]}>Common</color>";
				emoteLoadoutUIElementsList[5].loadoutName = "Complementary";
				emoteLoadoutUIElementsList[6].loadoutName = "All";
				SaveManager.LoadFavoritedEmotes();
				emoteLoadouts = new List<List<UnlockableEmote>>
				{
					StartOfRoundPatcher.unlockedFavoriteEmotes,
					StartOfRoundPatcher.unlockedEmotesTier3,
					StartOfRoundPatcher.unlockedEmotesTier2,
					StartOfRoundPatcher.unlockedEmotesTier1,
					StartOfRoundPatcher.unlockedEmotesTier0,
					StartOfRoundPatcher.complementaryEmotes,
					StartOfRoundPatcher.unlockedEmotes
				};
				if (currentLoadoutIndex < 0 || currentLoadoutIndex >= emoteLoadouts.Count)
				{
					currentLoadoutIndex = emoteLoadouts.Count - 1;
				}
				InitializeAnimationRenderer();
				menuGameObject.SetActive(false);
			}
		}

		[HarmonyPatch(typeof(HUDManager), "Update")]
		[HarmonyPostfix]
		public static void GetInput()
		{
			//IL_0063: 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_0080: 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_0083: 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)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)previewPlayerAnimatorController == (Object)null || !isMenuOpen)
			{
				return;
			}
			if (EmoteLoadoutUIContainer.hovered || hoveredLoadoutUIIndex != -1)
			{
				if (hoveredEmoteUIIndex != -1)
				{
					OnHoveredNewElement(-1);
				}
				return;
			}
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)(Screen.width / 2), (float)(Screen.height / 2));
			Vector2 val3 = val - val2;
			int num = -1;
			if (((Vector2)(ref val3)).magnitude / (float)Screen.height >= 0.17f)
			{
				float num2 = Mathf.Atan2(val3.y, 0f - val3.x) * 57.29578f - 67.5f;
				if (num2 < 0f)
				{
					num2 += 360f;
				}
				num = Mathf.FloorToInt(num2 / 45f);
			}
			if (num != hoveredEmoteUIIndex)
			{
				OnHoveredNewElement(num);
			}
		}

		public static void OnHoveredNewLoadoutElement(int index)
		{
			if (hoveredLoadoutUIIndex == index)
			{
				return;
			}
			hoveredLoadoutUIIndex = index;
			foreach (EmoteLoadoutUIElement emoteLoadoutUIElements in emoteLoadoutUIElementsList)
			{
				emoteLoadoutUIElements.OnHover(emoteLoadoutUIElements.id == index);
			}
		}

		public static void OnHoveredNewElement(int index)
		{
			if (hoveredEmoteUIIndex != -1 && hoveredEmoteUIIndex != index)
			{
				emoteUIElementsList[hoveredEmoteUIIndex].OnHover(hovered: false);
			}
			if (index != -1)
			{
				emoteUIElementsList[index].OnHover();
			}
			hoveredEmoteUIIndex = index;
			SetPreviewAnimation(hoveredEmoteIndex);
		}

		public static void SwapPrevPage()
		{
			currentPage--;
			if (currentPage < 0)
			{
				currentPage = numPages - 1;
			}
			UpdateEmoteWheel();
		}

		public static void SwapNextPage()
		{
			currentPage++;
			if (currentPage >= numPages)
			{
				currentPage = 0;
			}
			UpdateEmoteWheel();
		}

		public static void UpdateEmoteWheel()
		{
			//IL_00b8: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			currentPage = Mathf.Clamp(currentPage, 0, numPages - 1);
			((TMP_Text)swapPageText).text = $"[{currentPage + 1} / {numPages}]\n[Mouse Scroll]";
			for (int i = 0; i < emoteLoadoutUIElementsList.Count; i++)
			{
				EmoteLoadoutUIElement emoteLoadoutUIElement = emoteLoadoutUIElementsList[i];
				emoteLoadoutUIElement.OnHover(hoveredLoadoutUIIndex == emoteLoadoutUIElement.id);
			}
			for (int j = 0; j < emoteUIElementsList.Count; j++)
			{
				EmoteUIElement emoteUIElement = emoteUIElementsList[j];
				int num = j + 8 * currentPage;
				((TMP_Text)emoteUIElement.textContainer).text = "";
				emoteUIElement.emote = null;
				Color baseColor = defaultUIColor;
				if (num < currentLoadoutEmotesList.Count)
				{
					UnlockableEmote unlockableEmote = currentLoadoutEmotesList[num];
					if (unlockableEmote != null)
					{
						emoteUIElement.emote = unlockableEmote;
						((TMP_Text)emoteUIElement.textContainer).text = unlockableEmote.displayName;
					}
				}
				emoteUIElement.baseColor = baseColor;
				emoteUIElement.OnHover(hovered: false);
			}
			if (hoveredEmoteUIIndex >= 0 && hoveredEmoteUIIndex < 8)
			{
				OnHoveredNewElement(hoveredEmoteUIIndex);
			}
		}

		public static void SetPreviewAnimation(int emoteIndex)
		{
			if (emoteIndex >= 0 && emoteIndex < currentLoadoutEmotesList.Count && currentLoadoutEmotesList[emoteIndex] != null)
			{
				UnlockableEmote unlockableEmote = currentLoadoutEmotesList[emoteIndex];
				previewPlayerObject.SetActive(true);
				((Behaviour)renderingCamera).enabled = true;
				previewPlayerAnimatorController["EmoteStart"] = unlockableEmote.animationClip;
				previewPlayerAnimatorController["EmoteLoop"] = (((Object)(object)unlockableEmote.transitionsToClip != (Object)null) ? unlockableEmote.transitionsToClip : null);
				previewPlayerAnimator.SetBool("hasTransition", (Object)(object)unlockableEmote.transitionsToClip != (Object)null);
				previewPlayerAnimator.Play("EmoteStart", 0, 0f);
				((TMP_Text)currentEmoteText).text = "[" + unlockableEmote.displayNameColorCoded + "]\n[MMB] " + (StartOfRoundPatcher.allFavoriteEmotes.Contains(unlockableEmote.emoteName) ? "Unfavorite" : "Favorite");
			}
			else
			{
				previewPlayerAnimatorController["EmoteStart"] = null;
				previewPlayerAnimatorController["EmoteLoop"] = null;
				previewPlayerObject.SetActive(false);
				((TMP_Text)currentEmoteText).text = "";
				DisableRenderCameraNextFrame();
			}
		}

		public static void DisableRenderCameraNextFrame()
		{
			((MonoBehaviour)HUDManager.Instance).StartCoroutine(DisableRenderCameraNextFrameCoroutine());
			static IEnumerator DisableRenderCameraNextFrameCoroutine()
			{
				yield return null;
				((Behaviour)renderingCamera).enabled = false;
			}
		}

		public static void SetCurrentEmoteLoadout(int loadoutIndex)
		{
			if (currentLoadoutIndex != loadoutIndex)
			{
				currentPage = 0;
				currentLoadoutIndex = loadoutIndex;
				UpdateEmoteWheel();
			}
		}

		public static void ToggleFavoriteHoveredEmote()
		{
			if (isMenuOpen && previewingEmote != null)
			{
				string emoteName = previewingEmote.emoteName;
				if (StartOfRoundPatcher.allFavoriteEmotes.Contains(emoteName))
				{
					StartOfRoundPatcher.allFavoriteEmotes.Remove(emoteName);
				}
				else
				{
					StartOfRoundPatcher.allFavoriteEmotes.Add(emoteName);
				}
				StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes();
				SaveManager.SaveFavoritedEmotes();
				UpdateEmoteWheel();
			}
		}

		public static void ToggleEmoteMenu()
		{
			if (!isMenuOpen)
			{
				OpenEmoteMenu();
			}
			else
			{
				CloseEmoteMenu();
			}
		}

		public static void OpenEmoteMenu()
		{
			menuGameObject.SetActive(true);
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			quickMenuManager.isMenuOpen = true;
			((Renderer)previewPlayerMesh).material = ((Renderer)localPlayerController.thisPlayerModel).material;
			UpdateEmoteWheel();
		}

		public static void CloseEmoteMenu()
		{
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			localPlayerController.isFreeCamera = false;
			menuGameObject.SetActive(false);
			quickMenuManager.CloseQuickMenu();
		}

		public static bool CanOpenEmoteMenu()
		{
			if ((quickMenuManager.isMenuOpen && !isMenuOpen) || (Object)(object)previewPlayerObject == (Object)null)
			{
				return false;
			}
			if (localPlayerController.isPlayerDead || localPlayerController.inTerminalMenu || localPlayerController.isTypingChat || localPlayerController.isPlayerDead || localPlayerController.inSpecialInteractAnimation || localPlayerController.inShockingMinigame || localPlayerController.isClimbingLadder || localPlayerController.isSinking)
			{
				return false;
			}
			return true;
		}

		private static void InitializeAnimationRenderer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00ee: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			renderingCamera = new GameObject("AnimationRenderingCamera").AddComponent<Camera>();
			Object.Destroy((Object)(object)((Component)renderingCamera).GetComponent<AudioListener>());
			renderingCamera.cullingMask = playerLayerMask;
			renderingCamera.clearFlags = (CameraClearFlags)2;
			renderingCamera.cameraType = (CameraType)4;
			renderingCamera.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0f);
			renderingCamera.allowHDR = false;
			renderingCamera.allowMSAA = false;
			renderingCamera.farClipPlane = 5f;
			renderTexture = new RenderTexture(1024, 1024, 24);
			renderTexture.format = (RenderTextureFormat)0;
			renderTexture.graphicsFormat = (GraphicsFormat)8;
			renderTexture.depthStencilFormat = (GraphicsFormat)92;
			renderingCamera.targetTexture = renderTexture;
			((Component)renderingCamera).transform.position = Vector3.down * 1000f;
			renderTextureImageUI.texture = (Texture)(object)renderTexture;
			Light val = new GameObject("Spotlight").AddComponent<Light>();
			val.type = (LightType)0;
			((Component)val).transform.position = ((Component)renderingCamera).transform.position;
			((Component)val).transform.parent = ((Component)renderingCamera).transform;
			((Component)val).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			val.intensity = 50f;
			val.range = 40f;
			val.innerSpotAngle = 100f;
			val.spotAngle = 120f;
			((Component)val).gameObject.layer = playerLayer;
			DisableRenderCameraNextFrame();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void InitializePlayerCloneRenderObject(PlayerControllerB __instance)
		{
			if (!((Object)(object)Plugin.radialMenuPrefab == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(InitPlayerCloneAfterSpawnAnimation());
			}
			IEnumerator InitPlayerCloneAfterSpawnAnimation()
			{
				yield return (object)new WaitForSeconds(2f);
				previewPlayerObject = Object.Instantiate<GameObject>(((Component)__instance).gameObject, ((Component)renderingCamera).transform);
				((Object)previewPlayerObject).name = "PreviewPlayerAnimationObject";
				GameObject modelGameObject = ((Component)previewPlayerObject.transform.Find("ScavengerModel")).gameObject;
				GameObject metarigGameObject = ((Component)modelGameObject.transform.Find("metarig")).gameObject;
				PlayerControllerB copyPlayerController = previewPlayerObject.GetComponentInChildren<PlayerControllerB>();
				((Renderer)copyPlayerController.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				previewPlayerMesh = copyPlayerController.thisPlayerModel;
				Object.Destroy((Object)(object)modelGameObject.GetComponentInChildren<LODGroup>());
				Object.DestroyImmediate((Object)(object)metarigGameObject.GetComponentInChildren<RigBuilder>());
				Object.DestroyImmediate((Object)(object)copyPlayerController.playerBodyAnimator);
				previewPlayerAnimator = metarigGameObject.AddComponent<Animator>();
				previewPlayerAnimatorController = new AnimatorOverrideController(Plugin.previewAnimatorController);
				previewPlayerAnimator.runtimeAnimatorController = (RuntimeAnimatorController)(object)previewPlayerAnimatorController;
				previewPlayerAnimator.Play("EmoteStart", 0, 0f);
				Object.Destroy((Object)(object)previewPlayerObject.GetComponent<NfgoPlayer>());
				foreach (Transform item in previewPlayerObject.transform)
				{
					Transform child3 = item;
					if (((Object)child3).name != "ScavengerModel")
					{
						Object.Destroy((Object)(object)((Component)child3).gameObject);
					}
				}
				foreach (Transform item2 in modelGameObject.transform)
				{
					Transform child2 = item2;
					if (((Object)child2).name != "LOD1" && ((Object)child2).name != "metarig")
					{
						Object.Destroy((Object)(object)((Component)child2).gameObject);
					}
				}
				foreach (Transform item3 in metarigGameObject.transform)
				{
					Transform child = item3;
					if (((Object)child).name != "spine")
					{
						Object.Destroy((Object)(object)((Component)child).gameObject);
					}
				}
				previewPlayerObject.transform.position = ((Component)renderingCamera).transform.position + ((Component)renderingCamera).transform.forward * 2.8f + Vector3.down * 1.35f;
				previewPlayerObject.transform.LookAt(new Vector3(((Component)renderingCamera).transform.position.x, previewPlayerObject.transform.position.y, ((Component)renderingCamera).transform.position.z));
				SetObjectLayerRecursive(previewPlayerObject, playerLayer);
				MonoBehaviour[] components = previewPlayerObject.GetComponents<MonoBehaviour>();
				foreach (MonoBehaviour script in components)
				{
					Object.Destroy((Object)(object)script);
				}
			}
		}

		private static void SetObjectLayerRecursive(GameObject obj, int layer)
		{
			if (!((Object)(object)obj == (Object)null))
			{
				obj.layer = layer;
				for (int i = 0; i < obj.transform.childCount; i++)
				{
					Transform child = obj.transform.GetChild(i);
					SetObjectLayerRecursive((child != null) ? ((Component)child).gameObject : null, layer);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool OnScrollMouse(CallbackContext context, PlayerControllerB __instance)
		{
			if (!isMenuOpen || (Object)(object)__instance != (Object)(object)localPlayerController || !((CallbackContext)(ref context)).performed)
			{
				return true;
			}
			if (((CallbackContext)(ref context)).ReadValue<float>() < 0f && !ConfigSettings.reverseEmoteWheelScrollDirection.Value)
			{
				SwapNextPage();
			}
			else
			{
				SwapPrevPage();
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ItemSecondaryUse_performed")]
		[HarmonyPrefix]
		public static bool PreventItemSecondaryUseInMenu(CallbackContext context)
		{
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ItemTertiaryUse_performed")]
		[HarmonyPrefix]
		public static bool PreventItemTertiaryUseInMenu(CallbackContext context)
		{
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Interact_performed")]
		[HarmonyPrefix]
		public static bool PreventInteractInMenu(CallbackContext context)
		{
			return !isMenuOpen;
		}

		[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
		[HarmonyPrefix]
		public static bool OnOpenQuickMenu()
		{
			if (isMenuOpen)
			{
				CloseEmoteMenu();
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		[HarmonyPostfix]
		public static void OnCloseQuickMenu()
		{
			if (isMenuOpen)
			{
				CloseEmoteMenu();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyPostfix]
		public static void OnLocalPlayerDeath(Vector3 bodyVelocity, PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController && isMenuOpen && __instance.isPlayerDead)
			{
				CloseEmoteMenu();
			}
		}
	}
	public class EmoteUIElement
	{
		public GameObject uiGameObject;

		public int id;

		public Image backgroundImage;

		public TextMeshPro textContainer;

		public Color baseColor;

		public UnlockableEmote emote;

		public void OnHover(bool hovered = true)
		{
			//IL_0002: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Color color = baseColor * (hovered ? 1f : 0.5f);
			color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha);
			((Graphic)backgroundImage).color = color;
		}
	}
	public class EmoteLoadoutUIElement : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public static int uiCount;

		public int id;

		public string loadoutName;

		public Image backgroundImage;

		public TextMeshPro textContainer;

		private void Awake()
		{
			id = uiCount++;
			backgroundImage = ((Component)this).GetComponentInChildren<Image>();
			textContainer = ((Component)this).GetComponentInChildren<TextMeshPro>();
		}

		private void Start()
		{
			((TMP_Text)textContainer).text = loadoutName;
		}

		public void OnHover(bool hovered = true)
		{
			//IL_0015: 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)
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			Color color = ((EmoteMenuManager.currentLoadoutIndex == id) ? EmoteMenuManager.selectedLoadoutUIColor : EmoteMenuManager.defaultUIColor) * (hovered ? 1f : 0.5f);
			color.a = (hovered ? EmoteMenuManager.hoveredAlpha : EmoteMenuManager.unhoveredAlpha);
			((Graphic)backgroundImage).color = color;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			EmoteMenuManager.OnHoveredNewLoadoutElement(id);
			OnHover();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			EmoteMenuManager.OnHoveredNewLoadoutElement(-1);
			OnHover(hovered: false);
		}
	}
	public class EmoteLoadoutUIContainer : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public static bool hovered;

		public void OnPointerEnter(PointerEventData eventData)
		{
			hovered = true;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			hovered = false;
		}
	}
	public class UnlockableEmote
	{
		public int emoteId;

		public string emoteName;

		public string randomEmotePoolName = "";

		public string displayName = "";

		public bool purchasable = true;

		public AnimationClip animationClip;

		public AnimationClip transitionsToClip = null;

		public List<UnlockableEmote> randomEmotePool;

		public bool complementary = false;

		public bool isPose = false;

		public bool canSyncEmote = false;

		public bool favorite = false;

		public int rarity = 0;

		public static string[] rarityColorCodes = new string[4]
		{
			ConfigSettings.emoteNameColorTier0.Value,
			ConfigSettings.emoteNameColorTier1.Value,
			ConfigSettings.emoteNameColorTier2.Value,
			ConfigSettings.emoteNameColorTier3.Value
		};

		public string displayNameColorCoded => $"<color={nameColor}>{displayName}</color>";

		public string rarityText
		{
			get
			{
				if (rarity == 0)
				{
					return "Common";
				}
				if (rarity == 1)
				{
					return "Uncommon";
				}
				if (rarity == 2)
				{
					return "Rare";
				}
				if (rarity == 3)
				{
					return "Legendary";
				}
				return "Invalid";
			}
		}

		public int price
		{
			get
			{
				int num = -1;
				if (complementary)
				{
					num = 0;
				}
				else if (rarity == 0)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier0;
				}
				else if (rarity == 1)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier1;
				}
				else if (rarity == 2)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier2;
				}
				else if (rarity == 3)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier3;
				}
				return (int)Mathf.Max((float)num * ConfigSync.instance.syncPriceMultiplierEmotesStore, 0f);
			}
		}

		public string nameColor => rarityColorCodes[rarity];
	}
	[HarmonyPatch]
	public static class Keybinds
	{
		private static InputAction OpenEmoteMenuAction;

		private static InputAction SelectEmoteUIAction;

		private static InputAction NextEmotePageAction;

		private static InputAction PrevEmotePageAction;

		private static InputAction FavoriteEmoteAction;

		private static InputAction RotatePlayerEmoteAction;

		public static InputAction RawScrollAction;

		public static bool holdingRotatePlayerModifier;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void InitializeHotkeys(PlayerControllerB __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			Plugin.Log("Initializing custom emote hotkeys.");
			OpenEmoteMenuAction = new InputAction((string)null, (InputActionType)0, ConfigSettings.openEmoteMenuKeybind.Value, "Press", (string)null, (string)null);
			SelectEmoteUIAction = new InputAction((string)null, (InputActionType)0, "<Mouse>/leftButton", "Press", (string)null, (string)null);
			PrevEmotePageAction = new InputAction((string)null, (InputActionType)0, "<Keyboard>/q", "Press", (string)null, (string)null);
			NextEmotePageAction = new InputAction((string)null, (InputActionType)0, "<Keyboard>/e", "Press", (string)null, (string)null);
			FavoriteEmoteAction = new InputAction((string)null, (InputActionType)0, "<Mouse>/middleButton", "Press", (string)null, (string)null);
			RotatePlayerEmoteAction = new InputAction((string)null, (InputActionType)0, ConfigSettings.rotateCharacterInEmoteKeybind.Value, "Press", (string)null, (string)null);
			RawScrollAction = new InputAction("Scroll", (InputActionType)0, "<Mouse>/scroll", (string)null, (string)null, (string)null);
			if (((Component)__instance).gameObject.activeSelf)
			{
				SubscribeToEvents();
			}
		}

		private static void SubscribeToEvents()
		{
			Plugin.Log("Subscribing to OnPressCustomEmoteKey events");
			OpenEmoteMenuAction.performed += OnPressOpenEmoteMenu;
			OpenEmoteMenuAction.canceled += OnPressOpenEmoteMenu;
			SelectEmoteUIAction.performed += OnSelectEmoteUI;
			PrevEmotePageAction.performed += OnSwapPrevEmotePage;
			NextEmotePageAction.performed += OnSwapNextEmotePage;
			FavoriteEmoteAction.performed += OnFavoriteEmote;
			RotatePlayerEmoteAction.performed += OnUpdateRotatePlayerEmoteModifier;
			RotatePlayerEmoteAction.canceled += OnUpdateRotatePlayerEmoteModifier;
			OpenEmoteMenuAction.Enable();
			SelectEmoteUIAction.Enable();
			PrevEmotePageAction.Enable();
			NextEmotePageAction.Enable();
			FavoriteEmoteAction.Enable();
			RotatePlayerEmoteAction.Enable();
			RawScrollAction.Enable();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)localPlayerController))
			{
				SubscribeToEvents();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)localPlayerController))
			{
				Plugin.Log("Unsubscribing from OnPressCustomEmoteKey events.");
				OpenEmoteMenuAction.performed -= OnPressOpenEmoteMenu;
				OpenEmoteMenuAction.canceled -= OnPressOpenEmoteMenu;
				SelectEmoteUIAction.performed -= OnSelectEmoteUI;
				PrevEmotePageAction.performed -= OnSwapPrevEmotePage;
				NextEmotePageAction.performed -= OnSwapNextEmotePage;
				FavoriteEmoteAction.performed -= OnFavoriteEmote;
				RotatePlayerEmoteAction.performed -= OnUpdateRotatePlayerEmoteModifier;
				RotatePlayerEmoteAction.canceled -= OnUpdateRotatePlayerEmoteModifier;
				OpenEmoteMenuAction.Disable();
				SelectEmoteUIAction.Disable();
				PrevEmotePageAction.Disable();
				NextEmotePageAction.Disable();
				FavoriteEmoteAction.Disable();
				RotatePlayerEmoteAction.Disable();
				RawScrollAction.Disable();
			}
		}

		private static void OnPressOpenEmoteMenu(CallbackContext context)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayerController == (Object)null)
			{
				return;
			}
			if (!EmoteMenuManager.isMenuOpen)
			{
				if (((CallbackContext)(ref context)).performed && EmoteMenuManager.CanOpenEmoteMenu())
				{
					EmoteMenuManager.OpenEmoteMenu();
				}
			}
			else if (ConfigSettings.toggleEmoteMenu.Value)
			{
				if (((CallbackContext)(ref context)).performed)
				{
					EmoteMenuManager.CloseEmoteMenu();
				}
			}
			else if (((CallbackContext)(ref context)).canceled)
			{
				if (EmoteMenuManager.hoveredEmoteIndex != -1)
				{
					PerformEmoteLocal(context);
				}
				EmoteMenuManager.CloseEmoteMenu();
			}
		}

		private static void OnSelectEmoteUI(CallbackContext context)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen)
			{
				if (EmoteMenuManager.hoveredLoadoutUIIndex != -1 && EmoteMenuManager.hoveredLoadoutUIIndex != EmoteMenuManager.currentLoadoutIndex)
				{
					EmoteMenuManager.SetCurrentEmoteLoadout(EmoteMenuManager.hoveredLoadoutUIIndex);
				}
				else if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count)
				{
					PerformEmoteLocal(context);
					EmoteMenuManager.CloseEmoteMenu();
				}
			}
		}

		private static void OnSwapPrevEmotePage(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen && EmoteMenuManager.numPages > 1)
			{
				EmoteMenuManager.SwapPrevPage();
			}
		}

		private static void OnSwapNextEmotePage(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen && EmoteMenuManager.numPages > 1)
			{
				EmoteMenuManager.SwapNextPage();
			}
		}

		public static void PerformEmoteLocal(CallbackContext context)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (EmoteMenuManager.hoveredEmoteIndex >= 0 && EmoteMenuManager.hoveredEmoteIndex < EmoteMenuManager.currentLoadoutEmotesList.Count)
			{
				UnlockableEmote unlockableEmote = EmoteMenuManager.currentLoadoutEmotesList[EmoteMenuManager.hoveredEmoteIndex];
				if (unlockableEmote != null)
				{
					localPlayerController.PerformEmote(context, -(unlockableEmote.emoteId + 1));
				}
			}
		}

		public static void OnFavoriteEmote(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null) && ((CallbackContext)(ref context)).performed && EmoteMenuManager.isMenuOpen && EmoteMenuManager.hoveredEmoteUIIndex != -1 && EmoteMenuManager.previewingEmote != null)
			{
				EmoteMenuManager.ToggleFavoriteHoveredEmote();
			}
		}

		public static void OnUpdateRotatePlayerEmoteModifier(CallbackContext context)
		{
			if (!((Object)(object)localPlayerController == (Object)null))
			{
				if (((CallbackContext)(ref context)).performed)
				{
					holdingRotatePlayerModifier = true;
				}
				else if (((CallbackContext)(ref context)).canceled)
				{
					holdingRotatePlayerModifier = false;
				}
			}
		}
	}
	[BepInPlugin("FlipMods.TooManyEmotes", "TooManyEmotes", "1.6.3")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		public static List<AnimationClip> customAnimationClips;

		public static Dictionary<string, AnimationClip> customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>();

		public static List<AnimationClip> complementaryAnimationClips;

		public static List<AnimationClip> animationClipsTier0;

		public static List<AnimationClip> animationClipsTier1;

		public static List<AnimationClip> animationClipsTier2;

		public static List<AnimationClip> animationClipsTier3;

		public static GameObject radialMenuPrefab;

		public static RuntimeAnimatorController previewAnimatorController;

		public static Dictionary<string, AudioClip> musicClips;

		private void Awake()
		{
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			customAnimationClips = new List<AnimationClip>();
			customAnimationClipsLoopDict = new Dictionary<string, AnimationClip>();
			complementaryAnimationClips = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_complementary"));
			animationClipsTier0 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_0"));
			animationClipsTier1 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_1"));
			animationClipsTier2 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_2"));
			animationClipsTier3 = new List<AnimationClip>(LoadEmoteAssetBundle("Assets/emotes_3"));
			customAnimationClips.AddRange(complementaryAnimationClips);
			customAnimationClips.AddRange(animationClipsTier0);
			customAnimationClips.AddRange(animationClipsTier1);
			customAnimationClips.AddRange(animationClipsTier2);
			customAnimationClips.AddRange(animationClipsTier3);
			foreach (AnimationClip customAnimationClip in customAnimationClips)
			{
				if (((Object)customAnimationClip).name.StartsWith("fn_"))
				{
					((Object)customAnimationClip).name = ((Object)customAnimationClip).name.Replace("fn_", "");
				}
				if (((Object)customAnimationClip).name.EndsWith("_loop"))
				{
					customAnimationClipsLoopDict.Add(((Object)customAnimationClip).name, customAnimationClip);
				}
			}
			foreach (AnimationClip value in customAnimationClipsLoopDict.Values)
			{
				customAnimationClips.Remove(value);
			}
			LoadRadialMenuAsset();
			_harmony = new Harmony("TooManyEmotes");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"TooManyEmotes loaded");
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		private static AnimationClip[] LoadEmoteAssetBundle(string assetBundleName)
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), assetBundleName);
				AssetBundle val = AssetBundle.LoadFromFile(text);
				AnimationClip[] array = val.LoadAllAssets<AnimationClip>();
				Log($"Successfully loaded {array.Length} animation clips from asset bundle: {assetBundleName}");
				return array;
			}
			catch
			{
				LogError("Failed to load emotes asset bundle: " + assetBundleName + ".");
				return (AnimationClip[])(object)new AnimationClip[0];
			}
		}

		public static void LoadRadialMenuAsset()
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)instance).Info.Location), "Assets/radial_menu");
				AssetBundle val = AssetBundle.LoadFromFile(text);
				radialMenuPrefab = val.LoadAsset<GameObject>("RadialMenu");
				previewAnimatorController = val.LoadAsset<RuntimeAnimatorController>("PreviewAnimatorController");
				Log("Successfully loaded radial menu asset.");
			}
			catch
			{
				LogError("Failed to load radial menu asset.");
			}
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogWarning(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.TooManyEmotes";

		public const string PLUGIN_NAME = "TooManyEmotes";

		public const string PLUGIN_VERSION = "1.6.3";
	}
}
namespace TooManyEmotes.Config
{
	public static class ConfigSettings
	{
		public static ConfigEntry<bool> unlockEverything;

		public static ConfigEntry<bool> disableRaritySystem;

		public static ConfigEntry<int> basePriceEmoteRaritySystemDisabled;

		public static ConfigEntry<int> startingEmoteCredits;

		public static ConfigEntry<float> addEmoteCreditsMultiplier;

		public static ConfigEntry<bool> purchaseEmotesWithDefaultCurrency;

		public static ConfigEntry<float> priceMultiplierEmotesStore;

		public static ConfigEntry<int> basePriceEmoteTier0;

		public static ConfigEntry<int> basePriceEmoteTier1;

		public static ConfigEntry<int> basePriceEmoteTier2;

		public static ConfigEntry<int> basePriceEmoteTier3;

		public static ConfigEntry<int> numEmotesStoreRotation;

		public static ConfigEntry<float> rotationChanceEmoteTier0;

		public static ConfigEntry<float> rotationChanceEmoteTier1;

		public static ConfigEntry<float> rotationChanceEmoteTier2;

		public static ConfigEntry<float> rotationChanceEmoteTier3;

		public static ConfigEntry<string> openEmoteMenuKeybind;

		public static ConfigEntry<string> rotateCharacterInEmoteKeybind;

		public static ConfigEntry<bool> toggleEmoteMenu;

		public static ConfigEntry<bool> reverseEmoteWheelScrollDirection;

		public static ConfigEntry<string> emoteNameColorTier0;

		public static ConfigEntry<string> emoteNameColorTier1;

		public static ConfigEntry<string> emoteNameColorTier2;

		public static ConfigEntry<string> emoteNameColorTier3;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			unlockEverything = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Server settings", "I am a Party Pooper", false, "[Host only] If true, every emote will be unlocked in your emote wheel at the start of the game.");
			disableRaritySystem = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Server settings", "DisableRaritySystem", false, "[Host only] If true, every emote will have the same likelyhood of appearing in the emote store.");
			basePriceEmoteRaritySystemDisabled = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "BasePriceEmote - Rarity System Disabled", 100, "[Host only] Base price of emotes if the rarity system is disabled.");
			startingEmoteCredits = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "StartingEmoteCredits", 100, "[Host only] The number of emote credits you start each game with.");
			addEmoteCreditsMultiplier = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "AddEmoteCreditsMultiplier", 0.5f, "[Host only] You gain emote credits based off this multiplier of normal group credits earned. Example: If set to the default, 0.5, and you earn 200 group credits, you will also gain 100 emote credits.");
			purchaseEmotesWithDefaultCurrency = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Server settings", "PurchaseEmotesWithDefaultCredits", false, "[Host only] Setting this to true will allow you to purchase emotes with normal group credits once you run out of emote credits.");
			purchaseEmotesWithDefaultCurrency = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Server settings", "PurchaseEmotesWithDefaultCredits", false, "[Host only] Setting this to true will allow you to purchase emotes with normal group credits once you run out of emote credits.");
			priceMultiplierEmotesStore = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "PriceMultiplierEmotesStore", 1f, "[Host only] Price multiplier for emotes in the store. Only applies if UnlockEverythingAtStart is false.");
			basePriceEmoteTier0 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "PriceCommonEmote", 50, "[Host only] The base price of [common]emotes in the store.");
			basePriceEmoteTier1 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "PriceUncommonEmote", 100, "[Host only] The base price of [uncommon] emotes in the store.");
			basePriceEmoteTier2 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "PriceRareEmote", 200, "[Host only] The base price of [rare] emotes in the store.");
			basePriceEmoteTier3 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "PriceLegendaryEmote", 300, "[Host only] The base price of [legendary] emotes in the store.");
			numEmotesStoreRotation = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server settings", "EmotesInStoreRotation", 6, "[Host only] The number of emotes that will be available at a time in the store. Only applies if UnlockEverythingAtStart is false.");
			rotationChanceEmoteTier0 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "RotationWeightCommonEmote", 0.55f, "[Host only] The likelyhood of [common] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier1 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "RotationWeightUncommonEmote", 0.35f, "[Host only] The likelyhood of [uncommon] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier2 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "RotationWeightRareEmote", 0.08f, "[Host only] The likelyhood of [rare] emotes appearing (per slot) in the store rotation.");
			rotationChanceEmoteTier3 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Server settings", "RotationWeightLegendaryEmote", 0.02f, "[Host only] The likelyhood of [legendary] emotes appearing (per slot) in the store rotation.");
			openEmoteMenuKeybind = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Client", "OpenEmoteMenuKeybind", "<Keyboard>/backquote", "Keybind for opening the emote radial menu.");
			rotateCharacterInEmoteKeybind = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Client", "RotateCharacterInEmoteKeybind", "<Keyboard>/leftAlt", "Keybind to hold to rotate character while performing a custom emote.");
			toggleEmoteMenu = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Client", "ToggleEmoteMenu", true, "If set to false, the emote menu will open upon pressing the related keybind, and close upon releasing, and will play the currently hovered emote.");
			reverseEmoteWheelScrollDirection = ((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Client", "ReverseEmoteWheelScrollDirection", false, "Reverses the page swapping direction in your emote when scrolling.");
			emoteNameColorTier0 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Accessibility", "CommonEmoteNameColor", "#00FF00", "The color of the [common] emote name in the terminal.");
			emoteNameColorTier1 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Accessibility", "UncommonEmoteNameColor", "#2828FF", "The color of the [uncommon] emote name in the terminal.");
			emoteNameColorTier2 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Accessibility", "RareEmoteNameColor", "#AA00EE", "The color of the [rare] emote name in the terminal.");
			emoteNameColorTier3 = ((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Accessibility", "LegendaryEmoteNameColor", "#FF2222", "The color of the [legendary] emote name in the terminal.");
			currentConfigEntries.Add(((ConfigEntryBase)unlockEverything).Definition.Key, (ConfigEntryBase)(object)unlockEverything);
			currentConfigEntries.Add(((ConfigEntryBase)disableRaritySystem).Definition.Key, (ConfigEntryBase)(object)disableRaritySystem);
			currentConfigEntries.Add(((ConfigEntryBase)basePriceEmoteRaritySystemDisabled).Definition.Key, (ConfigEntryBase)(object)basePriceEmoteRaritySystemDisabled);
			currentConfigEntries.Add(((ConfigEntryBase)startingEmoteCredits).Definition.Key, (ConfigEntryBase)(object)startingEmoteCredits);
			currentConfigEntries.Add(((ConfigEntryBase)addEmoteCreditsMultiplier).Definition.Key, (ConfigEntryBase)(object)addEmoteCreditsMultiplier);
			currentConfigEntries.Add(((ConfigEntryBase)purchaseEmotesWithDefaultCurrency).Definition.Key, (ConfigEntryBase)(object)purchaseEmotesWithDefaultCurrency);
			currentConfigEntries.Add(((ConfigEntryBase)priceMultiplierEmotesStore).Definition.Key, (ConfigEntryBase)(object)priceMultiplierEmotesStore);
			currentConfigEntries.Add(((ConfigEntryBase)basePriceEmoteTier0).Definition.Key, (ConfigEntryBase)(object)basePriceEmoteTier0);
			currentConfigEntries.Add(((ConfigEntryBase)basePriceEmoteTier1).Definition.Key, (ConfigEntryBase)(object)basePriceEmoteTier1);
			currentConfigEntries.Add(((ConfigEntryBase)basePriceEmoteTier2).Definition.Key, (ConfigEntryBase)(object)basePriceEmoteTier2);
			currentConfigEntries.Add(((ConfigEntryBase)basePriceEmoteTier3).Definition.Key, (ConfigEntryBase)(object)basePriceEmoteTier3);
			currentConfigEntries.Add(((ConfigEntryBase)numEmotesStoreRotation).Definition.Key, (ConfigEntryBase)(object)numEmotesStoreRotation);
			currentConfigEntries.Add(((ConfigEntryBase)rotationChanceEmoteTier0).Definition.Key, (ConfigEntryBase)(object)rotationChanceEmoteTier0);
			currentConfigEntries.Add(((ConfigEntryBase)rotationChanceEmoteTier1).Definition.Key, (ConfigEntryBase)(object)rotationChanceEmoteTier1);
			currentConfigEntries.Add(((ConfigEntryBase)rotationChanceEmoteTier2).Definition.Key, (ConfigEntryBase)(object)rotationChanceEmoteTier2);
			currentConfigEntries.Add(((ConfigEntryBase)rotationChanceEmoteTier3).Definition.Key, (ConfigEntryBase)(object)rotationChanceEmoteTier3);
			currentConfigEntries.Add(((ConfigEntryBase)openEmoteMenuKeybind).Definition.Key, (ConfigEntryBase)(object)openEmoteMenuKeybind);
			currentConfigEntries.Add(((ConfigEntryBase)rotateCharacterInEmoteKeybind).Definition.Key, (ConfigEntryBase)(object)rotateCharacterInEmoteKeybind);
			currentConfigEntries.Add(((ConfigEntryBase)toggleEmoteMenu).Definition.Key, (ConfigEntryBase)(object)toggleEmoteMenu);
			currentConfigEntries.Add(((ConfigEntryBase)reverseEmoteWheelScrollDirection).Definition.Key, (ConfigEntryBase)(object)reverseEmoteWheelScrollDirection);
			currentConfigEntries.Add(((ConfigEntryBase)emoteNameColorTier0).Definition.Key, (ConfigEntryBase)(object)emoteNameColorTier0);
			currentConfigEntries.Add(((ConfigEntryBase)emoteNameColorTier1).Definition.Key, (ConfigEntryBase)(object)emoteNameColorTier1);
			currentConfigEntries.Add(((ConfigEntryBase)emoteNameColorTier2).Definition.Key, (ConfigEntryBase)(object)emoteNameColorTier2);
			currentConfigEntries.Add(((ConfigEntryBase)emoteNameColorTier3).Definition.Key, (ConfigEntryBase)(object)emoteNameColorTier3);
			float value = rotationChanceEmoteTier0.Value;
			value += rotationChanceEmoteTier1.Value;
			value += rotationChanceEmoteTier2.Value;
			value += rotationChanceEmoteTier3.Value;
			if (value != 1f && value != 0f)
			{
				ConfigEntry<float> obj = rotationChanceEmoteTier0;
				obj.Value /= value;
				ConfigEntry<float> obj2 = rotationChanceEmoteTier1;
				obj2.Value /= value;
				ConfigEntry<float> obj3 = rotationChanceEmoteTier2;
				obj3.Value /= value;
				ConfigEntry<float> obj4 = rotationChanceEmoteTier3;
				obj4.Value /= value;
				((BaseUnityPlugin)Plugin.instance).Config.Save();
			}
			TryRemoveOldConfigSettings();
			ConfigSync.BuildDefaultConfigSync();
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				Plugin.Log("Cleaning old config entries");
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
}
namespace TooManyEmotes.Networking
{
	[Serializable]
	[HarmonyPatch]
	public class ConfigSync
	{
		public static bool isSynced;

		public static ConfigSync defaultConfig;

		public static ConfigSync instance;

		public bool syncUnlockEverything;

		public bool syncDisableRaritySystem;

		public int syncStartingEmoteCredits;

		public float syncAddEmoteCreditsMultiplier;

		public bool syncPurchaseEmotesWithDefaultCurrency;

		public float syncPriceMultiplierEmotesStore;

		public int syncBasePriceEmoteTier0;

		public int syncBasePriceEmoteTier1;

		public int syncBasePriceEmoteTier2;

		public int syncBasePriceEmoteTier3;

		public int syncNumEmotesStoreRotation;

		public float syncRotationChanceEmoteTier0;

		public float syncRotationChanceEmoteTier1;

		public float syncRotationChanceEmoteTier2;

		public float syncRotationChanceEmoteTier3;

		public ConfigSync()
		{
			syncUnlockEverything = ConfigSettings.unlockEverything.Value;
			syncDisableRaritySystem = ConfigSettings.disableRaritySystem.Value;
			syncStartingEmoteCredits = ConfigSettings.startingEmoteCredits.Value;
			syncAddEmoteCreditsMultiplier = ConfigSettings.addEmoteCreditsMultiplier.Value;
			syncPurchaseEmotesWithDefaultCurrency = ConfigSettings.purchaseEmotesWithDefaultCurrency.Value;
			syncPriceMultiplierEmotesStore = ConfigSettings.priceMultiplierEmotesStore.Value;
			syncNumEmotesStoreRotation = ConfigSettings.numEmotesStoreRotation.Value;
			syncRotationChanceEmoteTier0 = ConfigSettings.rotationChanceEmoteTier0.Value;
			syncRotationChanceEmoteTier1 = ConfigSettings.rotationChanceEmoteTier1.Value;
			syncRotationChanceEmoteTier2 = ConfigSettings.rotationChanceEmoteTier2.Value;
			syncRotationChanceEmoteTier3 = ConfigSettings.rotationChanceEmoteTier3.Value;
			if (ConfigSettings.disableRaritySystem.Value)
			{
				syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
				syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteRaritySystemDisabled.Value;
			}
			else
			{
				syncBasePriceEmoteTier0 = ConfigSettings.basePriceEmoteTier0.Value;
				syncBasePriceEmoteTier1 = ConfigSettings.basePriceEmoteTier1.Value;
				syncBasePriceEmoteTier2 = ConfigSettings.basePriceEmoteTier2.Value;
				syncBasePriceEmoteTier3 = ConfigSettings.basePriceEmoteTier3.Value;
			}
		}

		public static void BuildDefaultConfigSync()
		{
			defaultConfig = new ConfigSync();
			instance = new ConfigSync();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init(PlayerControllerB __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)__instance))
			{
				return;
			}
			isSynced = false;
			if (NetworkManager.Singleton.IsServer)
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncServerRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncServerRpc));
				isSynced = true;
				if (!instance.syncUnlockEverything)
				{
					return;
				}
				{
					foreach (UnlockableEmote allUnlockableEmote in StartOfRoundPatcher.allUnlockableEmotes)
					{
						StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote);
					}
					return;
				}
			}
			foreach (UnlockableEmote allUnlockableEmote2 in StartOfRoundPatcher.allUnlockableEmotes)
			{
				StartOfRoundPatcher.UnlockEmoteLocal(allUnlockableEmote2);
			}
			NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestConfigSyncClientRpc", new HandleNamedMessageDelegate(OnRequestConfigSyncClientRpc));
			RequestConfigSync();
		}

		public static void RequestConfigSync()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Requesting config sync from server");
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(0, (Allocator)2, -1);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncServerRpc", 0uL, val, (NetworkDelivery)3);
			}
			else
			{
				Plugin.LogError("Failed to send unlocked emote update to server.");
			}
		}

		private static void OnRequestConfigSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_004e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsServer)
			{
				Plugin.Log("Receiving config sync request from client: " + clientId);
				byte[] array = SerializeConfigToByteArray(instance);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4 + array.Length, (Allocator)2, -1);
				int num = array.Length;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestConfigSyncClientRpc", clientId, val, (NetworkDelivery)3);
			}
		}

		private static void OnRequestConfigSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient)
			{
				return;
			}
			if (((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
				if (((FastBufferReader)(ref reader)).TryBeginRead(num))
				{
					Plugin.Log("Receiving config sync from server.");
					byte[] data = new byte[num];
					((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
					instance = DeserializeFromByteArray(data);
					isSynced = true;
					if (StartOfRoundPatcher.allUnlockableEmotes != null && StartOfRoundPatcher.unlockedEmotes != null)
					{
						StartOfRoundPatcher.ResetProgressLocal();
						if (instance.syncUnlockEverything)
						{
							StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.allUnlockableEmotes);
						}
						else
						{
							StartOfRoundPatcher.UnlockEmotesLocal(StartOfRoundPatcher.complementaryEmotes);
						}
						StartOfRoundPatcher.UpdateUnlockedFavoriteEmotes();
					}
				}
				else
				{
					Plugin.LogError("Error receiving sync from server.");
				}
			}
			else
			{
				Plugin.LogError("Error receiving bytes length.");
			}
		}

		public static byte[] SerializeConfigToByteArray(ConfigSync config)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			MemoryStream memoryStream = new MemoryStream();
			binaryFormatter.Serialize(memoryStream, config);
			return memoryStream.ToArray();
		}

		public static ConfigSync DeserializeFromByteArray(byte[] data)
		{
			MemoryStream serializationStream = new MemoryStream(data);
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			return (ConfigSync)binaryFormatter.Deserialize(serializationStream);
		}
	}
	[HarmonyPatch]
	public static class EmoteSyncManager
	{
		public static bool requestedSync;

		public static bool isSynced;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			isSynced = NetworkManager.Singleton.IsServer;
			requestedSync = NetworkManager.Singleton.IsServer;
			if (NetworkManager.Singleton.IsServer)
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncServerRpc", new HandleNamedMessageDelegate(OnRequestSyncServerRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteServerRpc", new HandleNamedMessageDelegate(OnUnlockEmoteServerRpc));
			}
			else
			{
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRequestSyncClientRpc", new HandleNamedMessageDelegate(OnRequestSyncClientRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnUnlockEmoteClientRpc", new HandleNamedMessageDelegate(OnUnlockEmoteClientRpc));
				NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("TooManyEmotes-OnRotateEmotesClientRpc", new HandleNamedMessageDelegate(RotateEmoteSelectionClientRpc));
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		public static void RequestSyncAfterConfigUpdate(PlayerControllerB __instance)
		{
			if (!isSynced && !requestedSync && ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController)
			{
				SendSyncRequest();
				requestedSync = true;
			}
		}

		public static void SendSyncRequest()
		{
			//IL_003c: 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)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient)
			{
				Plugin.Log("Sending sync request to server.");
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref StartOfRound.Instance.localPlayerController.actualClientId, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestSyncServerRpc", 0uL, val, (NetworkDelivery)3);
			}
		}

		private static void OnRequestSyncServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0033: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00c3: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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)
			if (NetworkManager.Singleton.IsServer)
			{
				bool flag = true;
				ulong num = 0uL;
				if (((FastBufferReader)(ref reader)).TryBeginRead(8))
				{
					((FastBufferReader)(ref reader)).ReadValue<ulong>(ref num, default(ForPrimitives));
					flag = false;
					Plugin.Log("Receiving sync request from client: " + clientId);
				}
				else
				{
					Plugin.Log("Syncing with all clients.");
				}
				int num2 = 0;
				if (!ConfigSync.instance.syncUnlockEverything)
				{
					num2 = StartOfRoundPatcher.unlockedEmotes.Count;
				}
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(12 + 4 * Mathf.Max(num2, 0), (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TerminalPatcher.currentEmoteCredits, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num2, default(ForPrimitives));
				for (int i = 0; i < num2; i++)
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref StartOfRoundPatcher.unlockedEmotes[i].emoteId, default(ForPrimitives));
				}
				if (flag)
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("TooManyEmotes-OnRequestSyncClientRpc", val, (NetworkDelivery)3);
				}
				else
				{
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnRequestSyncClientRpc", num, val, (NetworkDelivery)3);
				}
			}
		}

		private static void OnRequestSyncClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			if (!NetworkManager.Singleton.IsClient)
			{
				return;
			}
			isSynced = true;
			if (((FastBufferReader)(ref reader)).TryBeginRead(12))
			{
				StartOfRoundPatcher.ResetProgressLocal();
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.currentEmoteCredits, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
				TerminalPatcher.RotateNewEmoteSelection();
				if (num <= 0)
				{
					if (num == -1)
					{
						StartOfRoundPatcher.ResetEmotesLocal();
					}
				}
				else
				{
					if (!((FastBufferReader)(ref reader)).TryBeginRead(4 * num))
					{
						Plugin.LogError("Error receiving emotes sync from server.");
						return;
					}
					int emoteId = default(int);
					for (int i = 0; i < num; i++)
					{
						((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
					}
				}
				isSynced = true;
				Plugin.Log("Received sync from server.");
			}
			else
			{
				Plugin.LogError("Error receiving sync from server.");
			}
		}

		public static void SendOnUnlockEmoteUpdate(int emoteId, int emoteCreditsUsed = -1)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
			Plugin.Log("Sending unlocked emote update to server. Emote id: " + emoteId);
			((FastBufferWriter)(ref val)).WriteValue<int>(ref emoteCreditsUsed, default(ForPrimitives));
			int num = 1;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref num, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValue<int>(ref emoteId, default(ForPrimitives));
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnUnlockEmoteServerRpc", 0uL, val, (NetworkDelivery)3);
		}

		public static void SendOnUnlockEmoteUpdateMulti(int emoteCreditsUsed = -1)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(8 + 4 * StartOfRoundPatcher.unlockedEmotes.Count, (Allocator)2, -1);
			Plugin.Log("Sending all unlocked emotes update to server.");
			((FastBufferWriter)(ref val)).WriteValue<int>(ref emoteCreditsUsed, default(ForPrimitives));
			int count = StartOfRoundPatcher.unlockedEmotes.Count;
			((FastBufferWriter)(ref val)).WriteValue<int>(ref count, default(ForPrimitives));
			foreach (UnlockableEmote unlockedEmote in StartOfRoundPatcher.unlockedEmotes)
			{
				((FastBufferWriter)(ref val)).WriteValue<int>(ref unlockedEmote.emoteId, default(ForPrimitives));
			}
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("TooManyEmotes-OnUnlockEmoteServerRpc", 0uL, val, (NetworkDelivery)3);
		}

		private static void OnUnlockEmoteServerRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsServer)
			{
				return;
			}
			if (((FastBufferReader)(ref reader)).TryBeginRead(8))
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
				int num2 = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
				if (num != -1)
				{
					TerminalPatcher.currentEmoteCredits = num;
				}
				Plugin.Log("Receiving unlocked emote update from client for " + num2 + " emotes.");
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(8 + 4 * num2, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref TerminalPatcher.currentEmoteCredits, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num2, default(ForPrimitives));
				if (((FastBufferReader)(ref reader)).TryBeginRead(4 * num2))
				{
					int emoteId = default(int);
					for (int i = 0; i < num2; i++)
					{
						((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
						((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref emoteId, default(ForPrimitives));
					}
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("TooManyEmotes-OnUnlockEmoteClientRpc", val, (NetworkDelivery)3);
				}
				else
				{
					Plugin.LogError("Failed to receive unlocked emote updates from client. Expected updates: " + num2);
				}
			}
			else
			{
				Plugin.LogError("Failed to receive unlocked emote update from client.");
			}
		}

		private static void OnUnlockEmoteClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
			{
				return;
			}
			if (((FastBufferReader)(ref reader)).TryBeginRead(8))
			{
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num, default(ForPrimitives));
				int num2 = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref num2, default(ForPrimitives));
				if (num != -1)
				{
					TerminalPatcher.currentEmoteCredits = num;
				}
				if (((FastBufferReader)(ref reader)).TryBeginRead(4 * num2))
				{
					int emoteId = default(int);
					for (int i = 0; i < num2; i++)
					{
						((FastBufferReader)(ref reader)).ReadValue<int>(ref emoteId, default(ForPrimitives));
						Plugin.Log("Receiving unlocked emote update from server. Emote id: " + emoteId);
						StartOfRoundPatcher.UnlockEmoteLocal(emoteId);
					}
				}
				else
				{
					Plugin.LogError("Failed to receive unlocked emote updates from client. Expected updates: " + num2);
				}
			}
			else
			{
				Plugin.LogError("Failed to receive unlocked emote update from client.");
			}
		}

		public static void RotateEmoteSelectionServerRpc(int overrideSeed = 0)
		{
			//IL_0052: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
			{
				TerminalPatcher.emoteStoreSeed = ((overrideSeed == 0) ? Random.Range(0, 1000000000) : overrideSeed);
				TerminalPatcher.RotateNewEmoteSelection();
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
				((FastBufferWriter)(ref val)).WriteValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("TooManyEmotes-OnRotateEmotesClientRpc", val, (NetworkDelivery)3);
			}
		}

		private static void RotateEmoteSelectionClientRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer && ((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				((FastBufferReader)(ref reader)).ReadValue<int>(ref TerminalPatcher.emoteStoreSeed, default(ForPrimitives));
				TerminalPatcher.RotateNewEmoteSelection();
			}
		}
	}
}
namespace TooManyEmotes.CompatibilityPatcher
{
	[HarmonyPatch]
	internal class MoreEmotesPatcher
	{
		public static bool loadedMoreEmotes;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPostfix]
		public static void ApplyPatch()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			if (!Plugin.IsModLoaded("MoreEmotes") || !Chainloader.PluginInfos.TryGetValue("MoreEmotes", out var value))
			{
				return;
			}
			Assembly assembly = ((object)value.Instance).GetType().Assembly;
			if (assembly != null)
			{
				Plugin.Log("Applying compatibility patch for More_Emotes");
				Type type = assembly.GetType("MoreEmotes.Patch.EmotePatch");
				FieldInfo field = type.GetField("local", BindingFlags.Static | BindingFlags.Public);
				RuntimeAnimatorController val = (RuntimeAnimatorController)field.GetValue(null);
				if ((Object)(object)val != (Object)null && !(val is AnimatorOverrideController))
				{
					field.SetValue(null, (object?)new AnimatorOverrideController(val));
				}
				FieldInfo field2 = type.GetField("others", BindingFlags.Static | BindingFlags.Public);
				RuntimeAnimatorController val2 = (RuntimeAnimatorController)field2.GetValue(null);
				if ((Object)(object)val2 != (Object)null && !(val2 is AnimatorOverrideController))
				{
					field2.SetValue(null, (object?)new AnimatorOverrideController(val2));
				}
			}
		}
	}
	internal class BiggerLobbyPatcher
	{
		public static bool loadedBiggerLobby;

		[HarmonyPatch(typeof(NetworkSceneManager), "PopulateScenePlacedObjects")]
		[HarmonyPostfix]
		public static void ApplyPatch()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			if (!Plugin.IsModLoaded("BiggerLobby"))
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			for (int i = 0; i < instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB obj = instance.allPlayerScripts[i];
				object obj2;
				if (obj == null)
				{
					obj2 = null;
				}
				else
				{
					Animator playerBodyAnimator = obj.playerBodyAnimator;
					obj2 = ((playerBodyAnimator != null) ? playerBodyAnimator.runtimeAnimatorController : null);
				}
				if ((Object)obj2 != (Object)null)
				{
					instance.allPlayerScripts[i].playerBodyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(instance.otherClientsAnimatorController);
				}
			}
			loadedBiggerLobby = true;
		}
	}
	[HarmonyPatch]
	internal class MoreCompanyPatcher
	{
		public static bool loadedMoreCompany = false;

		public static List<GameObject> cosmeticInstances = new List<GameObject>();

		[HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")]
		[HarmonyPostfix]
		public static void ApplyPatch()
		{
			//IL_00ae: 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)
			if (!Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				return;
			}
			CosmeticApplication val = Object.FindObjectOfType<CosmeticApplication>();
			if (CosmeticRegistry.locallySelectedCosmetics.Count <= 0 || val.spawnedCosmetics.Count > 0)
			{
				return;
			}
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				val.ApplyCosmetic(locallySelectedCosmetic, true);
			}
			foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
				SetAllChildrenLayer(((Component)spawnedCosmetic).transform, 23);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, int layer)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			((Component)transform).gameObject.layer = layer;
			foreach (Transform item in transform)
			{
				Transform transform2 = item;
				SetAllChildrenLayer(transform2, layer);
			}
		}
	}
	[HarmonyPatch]
	internal class MirrorDecorPatcher
	{
		public static bool loadedMirrorDecor;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPrefix]
		public static void ApplyPatch()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.IsModLoaded("quackandcheese.mirrordecor"))
			{
				loadedMirrorDecor = true;
				ThirdPersonEmoteController.localPlayerBodyLayer = 23;
				ThirdPersonEmoteController.defaultShadowCastingMode = (ShadowCastingMode)1;
				Plugin.Log("Applied patch for MirrorDecor");
			}
		}
	}
}
namespace TooManyEmotes.Patches
{
	[HarmonyPatch]
	public static class BoomboxMusicPlayer
	{
		public static List<BoomboxItem> allBoomboxes = new List<BoomboxItem>();

		[HarmonyPatch(typeof(BoomboxItem), "Start")]
		[HarmonyPostfix]
		public static void AddBoomboxToPool(BoomboxItem __instance)
		{
		}

		public static void OnPlayEmoteWithMusic(UnlockableEmote emote, PlayerControllerB playerController)
		{
			if (Plugin.musicClips.ContainsKey(emote.emoteName))
			{
				BoomboxItem nearestBoombox = GetNearestBoombox(playerController);
				if (!((Object)(object)nearestBoombox == (Object)null) && (!nearestBoombox.isPlayingMusic || !Plugin.musicClips.ContainsKey(((Object)nearestBoombox.boomboxAudio.clip).name)))
				{
					AudioClip val = Plugin.musicClips[emote.emoteName];
					nearestBoombox.boomboxAudio.PlayOneShot(val);
				}
			}
		}

		public static BoomboxItem GetNearestBoombox(PlayerControllerB playerController)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			BoomboxItem result = null;
			float num = 10f;
			foreach (BoomboxItem allBoombox in allBoomboxes)
			{
				float num2 = Vector3.Distance(((Component)playerController).transform.position, ((Component)allBoombox).transform.position);
				if ((Object)(object)allBoombox != (Object)null && num2 < num)
				{
					result = allBoombox;
					num = num2;
				}
			}
			return result;
		}
	}
	[HarmonyPatch]
	public static class StartOfRoundPatcher
	{
		public static List<UnlockableEmote> allUnlockableEmotes;

		public static Dictionary<string, UnlockableEmote> allUnlockableEmotesDict;

		public static List<UnlockableEmote> complementaryEmotes;

		public static List<UnlockableEmote> unlockedFavoriteEmotes;

		public static List<string> allFavoriteEmotes;

		public static List<UnlockableEmote> allEmotesTier0;

		public static List<UnlockableEmote> allEmotesTier1;

		public static List<UnlockableEmote> allEmotesTier2;

		public static List<UnlockableEmote> allEmotesTier3;

		public static List<UnlockableEmote> unlockedEmotes;

		public static List<UnlockableEmote> unlockedEmotesTier0;

		public static List<UnlockableEmote> unlockedEmotesTier1;

		public static List<UnlockableEmote> unlockedEmotesTier2;

		public static List<UnlockableEmote> unlockedEmotesTier3;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPostfix]
		public static void CreateEmoteLists()
		{
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		public static void InitializeEmotes(StartOfRound __instance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Expected O, but got Unknown
			__instance.localClientAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(__instance.localClientAnimatorController);
			__instance.otherClientsAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(__instance.otherClientsAnimatorController);
			allUnlockableEmotes = new List<UnlockableEmote>();
			allUnlockableEmotesDict = new Dictionary<string, UnlockableEmote>();
			unlockedEmotes = new List<UnlockableEmote>();
			unlockedEmotesTier0 = new List<UnlockableEmote>();
			unlockedEmotesTier1 = new List<UnlockableEmote>();
			unlockedEmotesTier2 = new List<UnlockableEmote>();
			unlockedEmotesTier3 = new List<UnlockableEmote>();
			complementaryEmotes = new List<UnlockableEmote>();
			unlockedFavoriteEmotes = new List<UnlockableEmote>();
			allFavoriteEmotes = new List<string>();
			allEmotesTier0 = new List<UnlockableEmote>();
			allEmotesTier1 = new List<UnlockableEmote>();
			allEmotesTier2 = new List<UnlockableEmote>();
			allEmotesTier3 = new List<UnlockableEmote>();
			Dictionary<string, List<UnlockableEmote>> dictionary = new Dictionary<string, List<UnlockableEmote>>();
			for (int i = 0; i < Plugin.customAnimationClips.Count; i++)
			{
				AnimationClip val = Plugin.customAnimationClips[i];
				UnlockableEmote unlockableEmote = new UnlockableEmote
				{
					emoteId = i,
					emoteName = ((Object)val).name,
					displayName = "",
					animationClip = val,
					rarity = 0
				};
				unlockableEmote.rarity = (Plugin.animationClipsTier1.Contains(val) ? 1 : (Plugin.animationClipsTier2.Contains(val) ? 2 : (Plugin.animationClipsTier3.Contains(val) ? 3 : 0)));
				if (unlockableEmote.emoteName.Contains("_start"))
				{
					string key = unlockableEmote.emoteName.Replace("_start", "_loop");
					AnimationClip transitionsToClip = Plugin.customAnimationClipsLoopDict[key];
					unlockableEmote.transitionsToClip = transitionsToClip;
					unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_start", "");
				}
				if (unlockableEmote.emoteName.Contains("_pose"))
				{
					unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_pose", "");
					unlockableEmote.isPose = true;
				}
				if (unlockableEmote.emoteName.Contains("_random"))
				{
					unlockableEmote.randomEmotePoolName = unlockableEmote.emoteName.Substring(0, unlockableEmote.emoteName.IndexOf("_random"));
					if (!dictionary.ContainsKey(unlockableEmote.randomEmotePoolName))
					{
						dictionary.Add(unlockableEmote.randomEmotePoolName, new List<UnlockableEmote> { unlockableEmote });
					}
					else
					{
						unlockableEmote.purchasable = false;
						dictionary[unlockableEmote.randomEmotePoolName].Add(unlockableEmote);
					}
					unlockableEmote.randomEmotePool = dictionary[unlockableEmote.randomEmotePoolName];
					unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_random", "");
					unlockableEmote.displayName = unlockableEmote.randomEmotePoolName;
				}
				if ((Object)(object)unlockableEmote.transitionsToClip != (Object)null || ((Motion)unlockableEmote.animationClip).isLooping || unlockableEmote.isPose)
				{
					unlockableEmote.canSyncEmote = true;
				}
				if (unlockableEmote.displayName == "")
				{
					unlockableEmote.displayName = unlockableEmote.emoteName;
				}
				unlockableEmote.displayName = unlockableEmote.displayName.Replace('_', ' ').Trim(new char[1] { ' ' });
				unlockableEmote.displayName = char.ToUpper(unlockableEmote.displayName[0]) + unlockableEmote.displayName.Substring(1).ToLower();
				if (!allUnlockableEmotes.Contains(unlockableEmote))
				{
					allUnlockableEmotes.Add(unlockableEmote);
					allUnlockableEmotesDict.Add(unlockableEmote.emoteName, unlockableEmote);
				}
				if (Plugin.complementaryAnimationClips.Contains(val) && unlockableEmote.purchasable)
				{
					unlockableEmote.complementary = true;
					complementaryEmotes.Add(unlockableEmote);
				}
			}
			allUnlockableEmotes = (from item in allUnlockableEmotes
				orderby item.rarity, item.emoteName
				select item).ToList();
			int num = 0;
			foreach (UnlockableEmote allUnlockableEmote in allUnlockableEmotes)
			{
				allUnlockableEmote.emoteId = num++;
				if (allUnlockableEmote.rarity == 0)
				{
					allEmotesTier0.Add(allUnlockableEmote);
				}
				else if (allUnlockableEmote.rarity == 1)
				{
					allEmotesTier1.Add(allUnlockableEmote);
				}
				else if (allUnlockableEmote.rarity == 2)
				{
					allEmotesTier2.Add(allUnlockableEmote);
				}
				else if (allUnlockableEmote.rarity == 3)
				{
					allEmotesTier3.Add(allUnlockableEmote);
				}
			}
			SaveManager.LoadFavoritedEmotes();
			for (int j = 0; j < __instance.allPlayerScripts.Length; j++)
			{
				PlayerControllerB obj = __instance.allPlayerScripts[j];
				object obj2;
				if (obj == null)
				{
					obj2 = null;
				}
				else
				{
					Animator playerBodyAnimator = obj.playerBodyAnimator;
					obj2 = ((playerBodyAnimator != null) ? playerBodyAnimator.runtimeAnimatorController : null);
				}
				if ((Object)obj2 != (Object)null)
				{
					__instance.allPlayerScripts[j].playerBodyAnimator.runtimeAnimatorController = (RuntimeAnimatorController)new AnimatorOverrideController(__instance.otherClientsAnimatorController);
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		public static void OnServerStart(StartOfRound __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				UnlockEmotesLocal(ConfigSync.instance.syncUnlockEverything ? allUnlockableEmotes : complementaryEmotes);
				EmoteSyncManager.RotateEmoteSelectionServerRpc(TerminalPatcher.emoteStoreSeed);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		public static void ResetOverrideSeedFlag(StartOfRound __instance)
		{
			__instance.overrideRandomSeed = false;
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		[HarmonyPostfix]
		public static void ResetEmotesOnShipReset(StartOfRound __instance)
		{
			if (!ConfigSync.instance.syncUnlockEverything)
			{
				ResetProgressLocal();
			}
			if (NetworkManager.Singleton.IsServer)
			{
				EmoteSyncManager.RotateEmoteSelectionServerRpc();
			}
		}

		public static void ResetProgressLocal()
		{
			Plugin.Log("Resetting progression.");
			ResetEmotesLocal();
			TerminalPatcher.currentEmoteCredits = ConfigSync.instance.syncStartingEmoteCredits;
			TerminalPatcher.emoteStoreSeed = 0;
		}

		public static void ResetEmotesLocal()
		{
			unlockedEmotes.Clear();
			unlockedEmotesTier0.Clear();
			unlockedEmotesTier1.Clear();
			unlockedEmotesTier2.Clear();
			unlockedEmotesTier3.Clear();
			UnlockEmotesLocal(ConfigSync.instance.syncUnlockEverything ? allUnlockableEmotes : complementaryEmotes);
			UpdateUnlockedFavoriteEmotes();
		}

		public static void UpdateUnlockedFavoriteEmotes()
		{
			unlockedFavoriteEmotes.Clear();
			foreach (string allFavoriteEmote in allFavoriteEmotes)
			{
				if (allUnlockableEmotesDict.ContainsKey(allFavoriteEmote))
				{
					UnlockableEmote unlockableEmote = allUnlockableEmotesDict[allFavoriteEmote];
					if (unlockableEmote != null && unlockedEmotes.Contains(unlockableEmote))
					{
						unlockedFavoriteEmotes.Add(unlockableEmote);
					}
				}
				else
				{
					Plugin.LogWarning("Error loading favorited emote. Emote does not exist. The emote has likely been temporarily removed in this update.");
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesServerRpc")]
		[HarmonyPostfix]
		public static void SyncUnlockedEmotesWithClients(StartOfRound __instance)
		{
			if ((NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost) && !ConfigSync.instance.syncUnlockEverything)
			{
				Plugin.Log("Syncing unlocked emotes with clients.");
				EmoteSyncManager.SendOnUnlockEmoteUpdateMulti(TerminalPatcher.currentEmoteCredits);
			}
		}

		public static void UnlockEmotesLocal(List<UnlockableEmote> emotes)
		{
			foreach (UnlockableEmote emote in emotes)
			{
				UnlockEmoteLocal(emote);
			}
		}

		public static void UnlockEmoteLocal(int emoteId)
		{
			UnlockEmoteLocal((emoteId >= 0 && emoteId < allUnlockableEmotes.Count) ? allUnlockableEmotes[emoteId] : null);
		}

		public static void UnlockEmoteLocal(UnlockableEmote emote)
		{
			if (emote == null || unlockedEmotes.Contains(emote))
			{
				return;
			}
			if (emote.randomEmotePool != null)
			{
				foreach (UnlockableEmote item in emote.randomEmotePool)
				{
					if (unlockedEmotes.Contains(item))
					{
						return;
					}
				}
			}
			unlockedEmotes.Add(emote);
			if (emote.rarity == 3)
			{
				unlockedEmotesTier3.Add(emote);
			}
			else if (emote.rarity == 2)
			{
				unlockedEmotesTier2.Add(emote);
			}
			else if (emote.rarity == 1)
			{
				unlockedEmotesTier1.Add(emote);
			}
			else
			{
				unlockedEmotesTier0.Add(emote);
			}
			if (allFavoriteEmotes.Contains(emote.emoteName) && !unlockedFavoriteEmotes.Contains(emote))
			{
				unlockedFavoriteEmotes.Add(emote);
			}
		}

		public static void SortUnlockedEmotes()
		{
			unlockedEmotes = (from item in unlockedEmotes
				orderby item.rarity, item.emoteName
				select item).ToList();
		}
	}
	[HarmonyPatch]
	public class ThirdPersonEmoteController
	{
		public static GameObject playerHUDHelmetModel;

		public static Camera gameplayCamera;

		public static Camera emoteCamera;

		public static Transform emoteCameraPivot;

		public static int cameraCollideLayerMask = (1 << LayerMask.NameToLayer("Room")) | (1 << LayerMask.NameToLayer("PlaceableShipObject")) | (1 << LayerMask.NameToLayer("Terrain")) | (1 << LayerMask.NameToLayer("MiscLevelGeometry"));

		public static Vector2 clampCameraDistance = new Vector2(1.5f, 5f);

		public static float targetCameraDistance = 3f;

		public static int localPlayerBodyLayer = 0;

		public static ShadowCastingMode defaultShadowCastingMode = (ShadowCastingMode)3;

		public static string[] emoteControlTipLines = new string[1] { "Hold [ALT] : Rotate" };

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void InitLocalPlayerController(PlayerControllerB __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			gameplayCamera = __instance.gameplayCamera;
			if ((Object)(object)emoteCamera == (Object)null)
			{
				emoteCameraPivot = new GameObject("EmoteCameraPivot").transform;
				emoteCamera = new GameObject("EmoteCamera").AddComponent<Camera>();
				emoteCamera.CopyFrom(gameplayCamera);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
		[HarmonyPostfix]
		public static void OnPlayerSpawn(PlayerControllerB __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)emoteCamera).enabled = false;
			StartOfRound.Instance.SwitchCamera(StartOfRound.Instance.activeCamera);
			((Component)__instance.thisPlayerModelLOD1).gameObject.layer = 5;
			((Renderer)__instance.thisPlayerModelLOD1).shadowCastingMode = (ShadowCastingMode)3;
			((Renderer)__instance.thisPlayerModelLOD2).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)__instance.thisPlayerModelLOD2).enabled = false;
			((Component)__instance.thisPlayerModel).gameObject.layer = localPlayerBodyLayer;
			((Renderer)__instance.thisPlayerModel).shadowCastingMode = defaultShadowCastingMode;
			((Component)__instance.thisPlayerModelArms).gameObject.layer = 5;
			Camera obj = gameplayCamera;
			obj.cullingMask &= -8388609;
			Camera obj2 = emoteCamera;
			obj2.cullingMask |= 0x800000;
			Camera obj3 = emoteCamera;
			obj3.cullingMask |= 1 << localPlayerBodyLayer;
			Camera obj4 = emoteCamera;
			obj4.cullingMask &= -161;
			((Component)emoteCameraPivot).transform.parent = ((Component)__instance).transform;
			emoteCameraPivot.SetLocalPositionAndRotation(Vector3.up * 1.8f, Quaternion.identity);
			((Component)emoteCamera).transform.parent = emoteCameraPivot;
			((Component)emoteCamera).transform.SetLocalPositionAndRotation(Vector3.back * targetCameraDistance, Quaternion.identity);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlayerLookInput")]
		[HarmonyPrefix]
		public static bool UseFreeCamWhileEmoting(PlayerControllerB __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing refere

BepInEx/plugins/MoreHead.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using MoreCompany.Cosmetics;
using MoreCompany.Utils;
using MoreHead.Cosmetics;
using MoreHead.MoreScript;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MoreHead")]
[assembly: AssemblyDescription("A head mod")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreHead")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("011E6CD3-31C5-43C5-8681-EC192737BD7F")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MoreHead
{
	[BepInPlugin("Mhz.MoreHead", "MoreHead", "1.2.2")]
	public class PluginOne : BaseUnityPlugin
	{
		private const string PluginGuid = "Mhz.MoreHead";

		private const string PluginName = "MoreHead";

		private const string PluginVersion = "1.2.2";

		private static Harmony _harmony;

		private void Awake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (_harmony == null)
			{
				_harmony = new Harmony("Mhz.MoreHead");
				_harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreHead OK");
				Init();
			}
		}

		private void Init()
		{
			List<StreamCosmeticGeneric> cosmetics = new List<StreamCosmeticGeneric>
			{
				new YanCao(),
				new FanYanCao(),
				new MaoTou(),
				new Zhutou(),
				new Caomaoer(),
				new Dalalala(),
				new Heshuimao(),
				new Xiguamao(),
				new PaydayMask(),
				new Shoulianer(),
				new Shoubiaoer(),
				new Heijiaobu(),
				new Shouhuaner(),
				new Mianzhaoer(),
				new Koushuibudou(),
				new Gegedetou(),
				new Yashuaer(),
				new Yuguagua(),
				new Doulimaoer_1(),
				new Doulimaoer_2(),
				new Baonuanmao(),
				new Wushidaoer(),
				new Qingwashubaoer()
			};
			LoadAssets(cosmetics);
		}

		private void LoadAssets(IEnumerable<StreamCosmeticGeneric> cosmetics)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreHead Asset OK");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			foreach (StreamCosmeticGeneric cosmetic in cosmetics)
			{
				AssetBundle val = BundleUtilities.LoadBundleFromInternalAssembly(cosmetic.StreamingPath, executingAssembly);
				GameObject val2 = AssetBundleExtension.LoadPersistentAsset<GameObject>(val, ((CosmeticGeneric)cosmetic).gameObjectPath);
				if ((Object)(object)val2 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to find GameObject for cosmetic '" + ((CosmeticGeneric)cosmetic).cosmeticId + "' at path '" + ((CosmeticGeneric)cosmetic).gameObjectPath + "'"));
					continue;
				}
				if (((CosmeticGeneric)cosmetic).cosmeticId == "morehead.fanxiangyan")
				{
					GameObject gameObject = ((Component)val2.transform.Find("cigarette/yan/yanlizi")).gameObject;
					if ((Object)(object)gameObject == (Object)null)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)"No fanxiangyanlizi!");
					}
					else
					{
						gameObject.AddComponent<Huanse>();
						((BaseUnityPlugin)this).Logger.LogWarning((object)"fanxiangyanlizi ok.");
					}
				}
				Texture2D val3 = AssetBundleExtension.LoadPersistentAsset<Texture2D>(val, ((CosmeticGeneric)cosmetic).textureIconPath);
				if ((Object)(object)val3 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to find icon Texture2D for cosmetic '" + ((CosmeticGeneric)cosmetic).cosmeticId + " at path '" + ((CosmeticGeneric)cosmetic).textureIconPath + "'"));
				}
				else
				{
					CosmeticInstance val4 = val2.AddComponent<CosmeticInstance>();
					val4.cosmeticId = ((CosmeticGeneric)cosmetic).cosmeticId;
					val4.icon = val3;
					val4.cosmeticType = ((CosmeticGeneric)cosmetic).cosmeticType;
					CosmeticRegistry.cosmeticInstances.Add(((CosmeticGeneric)cosmetic).cosmeticId, val4);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Successfully loaded cosmetic: " + ((CosmeticGeneric)cosmetic).cosmeticId));
				}
			}
		}
	}
}
namespace MoreHead.Cosmetics
{
	public abstract class StreamCosmeticGeneric : CosmeticGeneric
	{
		public virtual string StreamingPath => string.Empty;
	}
	public class YanCao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yan";

		public override string gameObjectPath => "Assets/MoreHead/Yan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/YanTu.png";

		public override string StreamingPath => "morehead.more.yan1";
	}
	public class FanYanCao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.fanxiangyan";

		public override string gameObjectPath => "Assets/MoreHead/Fanxiangyan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Fanxiangyantu.png";

		public override string StreamingPath => "morehead.more.yan2";
	}
	public class MaoTou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.cathead";

		public override string gameObjectPath => "Assets/MoreHead/CatHead.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Cattu.png";

		public override string StreamingPath => "morehead.more.cathead";
	}
	public class Zhutou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.pighead";

		public override string gameObjectPath => "Assets/MoreHead/PigHead.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Zhutu.png";

		public override string StreamingPath => "morehead.more.pighead";
	}
	public class Caomaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.caomao";

		public override string gameObjectPath => "Assets/MoreHead/CaoMao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Caomaotu.png";

		public override string StreamingPath => "morehead.more.caomao";
	}
	public class Dalalala : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.xiangsuyanjing";

		public override string gameObjectPath => "Assets/MoreHead/YanJingEr.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Xiangsuyanjingtu.png";

		public override string StreamingPath => "morehead.more.yanjinger";
	}
	public class Heshuimao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.shuimao";

		public override string gameObjectPath => "Assets/MoreHead/ShuiMao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Shuimaotu.png";

		public override string StreamingPath => "morehead.more.shuimaoer";
	}
	public class Xiguamao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.xiguatou";

		public override string gameObjectPath => "Assets/MoreHead/XiguaTou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Xiguatu.png";

		public override string StreamingPath => "morehead.more.xiguanaodai";
	}
	public class PaydayMask : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.dallas";

		public override string gameObjectPath => "Assets/MoreHead/DallasMask.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Masktu.png";

		public override string StreamingPath => "morehead.more.paydaytou";
	}
	public class Shoulianer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.shoulian";

		public override string gameObjectPath => "Assets/MoreHead/Shoulian.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Shouliantu.png";

		public override string StreamingPath => "morehead.more.shoulian";
	}
	public class Shoubiaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.biao";

		public override string gameObjectPath => "Assets/MoreHead/Biao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Biaotu.png";

		public override string StreamingPath => "morehead.more.shoubiao";
	}
	public class Heijiaobu : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.heiweijin";

		public override string gameObjectPath => "Assets/MoreHead/Heiweijin.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Heiweijintu.png";

		public override string StreamingPath => "morehead.more.dianjiaobu";
	}
	public class Shouhuaner : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.jinshouhuan";

		public override string gameObjectPath => "Assets/MoreHead/Jinshouhuan.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Jinshouhuantu.png";

		public override string StreamingPath => "morehead.more.jinshouhuan";
	}
	public class Mianzhaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.mianzhao";

		public override string gameObjectPath => "Assets/MoreHead/Mianzhao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Mianzhaotu.png";

		public override string StreamingPath => "morehead.more.mianzhao";
	}
	public class Koushuibudou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.koushuibu";

		public override string gameObjectPath => "Assets/MoreHead/Koushuibu.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Koushuibutu.png";

		public override string StreamingPath => "morehead.more.koushuibudou";
	}
	public class Gegedetou : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.kunkuntou";

		public override string gameObjectPath => "Assets/MoreHead/Kuntou.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Kuntoutu.png";

		public override string StreamingPath => "morehead.more.jigetou";
	}
	public class Yashuaer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yashua";

		public override string gameObjectPath => "Assets/MoreHead/Yashuashuaya.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Yashuatu.png";

		public override string StreamingPath => "morehead.more.shuayaya";
	}
	public class Yuguagua : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.yuguaqi";

		public override string gameObjectPath => "Assets/MoreHead/Yugua.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Yuguatu.png";

		public override string StreamingPath => "morehead.more.yuguagua";
	}
	public class Doulimaoer_1 : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.douli1";

		public override string gameObjectPath => "Assets/MoreHead/Doulimao1.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Doulimaotu.png";

		public override string StreamingPath => "morehead.more.doulimao1";
	}
	public class Doulimaoer_2 : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.douli2";

		public override string gameObjectPath => "Assets/MoreHead/Doulimao2.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Doulimaotu.png";

		public override string StreamingPath => "morehead.more.doulimao2";
	}
	public class Baonuanmao : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.wula1";

		public override string gameObjectPath => "Assets/MoreHead/Wulamao1.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Wulamaotu.png";

		public override string StreamingPath => "morehead.more.wulamao1";
	}
	public class Wushidaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.dao2077";

		public override string gameObjectPath => "Assets/MoreHead/Wushidao2077.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Dao2077tu.png";

		public override string StreamingPath => "morehead.more.dao2077";
	}
	public class Qingwashubaoer : StreamCosmeticGeneric
	{
		public override string cosmeticId => "morehead.wabao";

		public override string gameObjectPath => "Assets/MoreHead/Qingwashubao.prefab";

		public override string textureIconPath => "Assets/MoreHead/ICON/Wabeibaotu.png";

		public override string StreamingPath => "morehead.more.qingwabaobao";
	}
}
namespace MoreHead.MoreScript
{
	public class Huanse : MonoBehaviour
	{
		private ParticleSystem _particle;

		private void Start()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			_particle = ((Component)this).GetComponent<ParticleSystem>();
			if ((Object)(object)_particle == (Object)null)
			{
				Debug.LogError((object)"NO ParticleSystem.");
				return;
			}
			MainModule main = _particle.main;
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "MainMenu")
			{
				Color val = default(Color);
				((Color)(ref val))..ctor(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val);
				PlayerPrefs.SetString("SavedColor", ColorUtility.ToHtmlStringRGB(val));
				PlayerPrefs.Save();
			}
			else
			{
				string @string = PlayerPrefs.GetString("SavedColor", "");
				if (!string.IsNullOrEmpty(@string))
				{
					@string = "#" + @string;
					Color val2 = default(Color);
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(ColorUtility.TryParseHtmlString(@string, ref val2) ? val2 : Color.yellow);
				}
			}
			MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
			Debug.LogWarning((object)((MinMaxGradient)(ref startColor)).color);
		}
	}
}

BepInEx/plugins/QuickDrop.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using QuickDrop.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("QuickDrop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickDrop")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("afd7a42f-ed64-41bc-84d5-180365c052a3")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace QuickDrop
{
	[BepInPlugin("Nases.QuickDrop", "Quick Drop", "1.0.0.0")]
	public class QuickDropMod : BaseUnityPlugin
	{
		private const string modGUID = "Nases.QuickDrop";

		private const string modName = "Quick Drop";

		private const string modVersion = "1.0.0.0";

		private readonly Harmony harmony = new Harmony("Nases.QuickDrop");

		private static QuickDropMod instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			mls = Logger.CreateLogSource("Nases.QuickDrop");
			mls.LogInfo((object)"Quick Drop Mod is active");
			harmony.PatchAll(typeof(QuickDropMod));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
		}
	}
}
namespace QuickDrop.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch
	{
		[HarmonyPatch("Discard_performed")]
		[HarmonyPrefix]
		private static void quickDropItemsPatch(PlayerControllerB __instance, ref bool ___isHoldingObject, ref GrabbableObject[] ___ItemSlots)
		{
			if (___isHoldingObject)
			{
				return;
			}
			MethodInfo method = typeof(PlayerControllerB).GetMethod("NextItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method2 = typeof(PlayerControllerB).GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
			if (!(method != null) || !(method2 != null))
			{
				return;
			}
			int currentItemSlot = __instance.currentItemSlot;
			object[] parameters = new object[1] { true };
			for (int num = (int)method.Invoke(__instance, parameters); num != currentItemSlot; num = (num + 1) % ___ItemSlots.Length)
			{
				if ((Object)(object)___ItemSlots[num] != (Object)null)
				{
					method2.Invoke(__instance, new object[2] { num, null });
					break;
				}
			}
		}
	}
}

BepInEx/plugins/LethalAPI.TerminalCommands.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalAPI.TerminalCommands.Attributes;
using LethalAPI.TerminalCommands.Commands;
using LethalAPI.TerminalCommands.Configs;
using LethalAPI.TerminalCommands.Models;
using LethalAPI.TerminalCommands.Patches;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

[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("ShimmyMySherbet, LethalAPI Modding Team")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A library that allows the creation of custom terminal commands for Lethal Company mods")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+5290c6d02b20cc3e4c96dd09d0f7234c78366019")]
[assembly: AssemblyProduct("LethalAPI.TerminalCommands")]
[assembly: AssemblyTitle("LethalAPI.TerminalCommands")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/LethalCompany/LethalAPI.TerminalCommands")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalAPI.TerminalCommands
{
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	public static class ParseSentencePatch
	{
		[HarmonyPrefix]
		public static bool ParsePrefix(Terminal __instance, ref TerminalNode __state)
		{
			__state = null;
			string command = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
			__state = CommandHandler.TryExecute(command, __instance);
			return (Object)(object)__state == (Object)null;
		}

		[HarmonyPostfix]
		public static TerminalNode ParsePostfix(TerminalNode __result, TerminalNode __state, Terminal __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			if ((Object)(object)__state != (Object)null)
			{
				TerminalSubmitPatch.LastNode = __state;
				return __state;
			}
			if ((int)__instance.videoPlayer.source == 1)
			{
				__instance.videoPlayer.source = (VideoSource)0;
			}
			TerminalSubmitPatch.LastNode = __result;
			return __result;
		}
	}
	[BepInPlugin("LethalAPI.TerminalCommands", "LethalAPI.TerminalCommands", "1.1.0")]
	public class TerminalCommandsPlugin : BaseUnityPlugin
	{
		private Harmony HarmonyInstance = new Harmony("LethalAPI.TerminalCommands");

		private TerminalModRegistry Terminal;

		private TerminalConfig TerminalConfig;

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalAPI.TerminalCommands is loading...");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Installing patches");
			HarmonyInstance.PatchAll(typeof(TerminalCommandsPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registering built-in Commands");
			Terminal = TerminalRegistry.CreateTerminalRegistry();
			Terminal.RegisterFrom<CommandInfoCommands>();
			TerminalConfig = Terminal.RegisterFrom<TerminalConfig>();
			Object.DontDestroyOnLoad((Object)(object)this);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalAPI.TerminalCommands is loaded!");
		}
	}
	public static class TerminalExtensions
	{
		public static void PlayVideoFile(this Terminal terminal, string filePath)
		{
			string url = "file:///" + filePath.Replace('\\', '/');
			terminal.PlayVideoLink(url);
		}

		public static void PlayVideoLink(this Terminal terminal, Uri url)
		{
			((MonoBehaviour)terminal).StartCoroutine(PlayVideoLink(url.AbsoluteUri, terminal));
		}

		public static void PlayVideoLink(this Terminal terminal, string url)
		{
			((MonoBehaviour)terminal).StartCoroutine(PlayVideoLink(url, terminal));
		}

		private static IEnumerator PlayVideoLink(string url, Terminal terminal)
		{
			yield return (object)new WaitForFixedUpdate();
			((Behaviour)terminal.terminalImage).enabled = true;
			terminal.terminalImage.texture = (Texture)(object)terminal.videoTexture;
			terminal.displayingPersistentImage = null;
			terminal.videoPlayer.clip = null;
			terminal.videoPlayer.source = (VideoSource)1;
			terminal.videoPlayer.url = url;
			((Behaviour)terminal.videoPlayer).enabled = true;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalAPI.TerminalCommands";

		public const string PLUGIN_NAME = "LethalAPI.TerminalCommands";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace LethalAPI.TerminalCommands.Patches
{
	[HarmonyPatch(typeof(Terminal), "selectTextFieldDelayed")]
	public static class SelectTextFieldPatch
	{
		[HarmonyPrefix]
		public static bool Prefix()
		{
			return false;
		}

		[HarmonyPostfix]
		public static void Postfix(Terminal __instance, ref IEnumerator __result)
		{
			__result = Patch(__instance);
		}

		private static IEnumerator Patch(Terminal terminal)
		{
			yield return (object)new WaitForSeconds(0.2f);
			terminal.screenText.ActivateInputField();
			((Selectable)terminal.screenText).Select();
		}
	}
	[HarmonyPatch(typeof(Terminal), "OnSubmit")]
	public static class TerminalSubmitPatch
	{
		private static ManualLogSource m_LogSource = new ManualLogSource("LethalAPI.TerminalCommands");

		public static TerminalNode LastNode { get; set; }

		[HarmonyPrefix]
		public static void Prefix()
		{
			LastNode = null;
		}

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			CodeInstruction[] array = instructions.ToArray();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (!(array[num].opcode != OpCodes.Callvirt))
				{
					if (array[num + 1].opcode != OpCodes.Ldarg_0)
					{
						ReportTranspileError("Ldarg_0 expected after final callVirt, not found");
						return array;
					}
					array[num + 1] = new CodeInstruction(OpCodes.Ret, (object)null);
					return array;
				}
			}
			ReportTranspileError("Failed to find Callvirt in backward scan");
			return array;
		}

		private static void ReportTranspileError(string message)
		{
			m_LogSource.LogError((object)("Failed to transpile OnSubmit to remove Scroll To Bottom. Did the method get modified in an update? (" + message + ")"));
			m_LogSource.LogWarning((object)"This won't break the mod, but it will cause some odd terminal scrolling behavior");
		}

		[HarmonyPostfix]
		public static void Postfix(Terminal __instance, ref Coroutine ___forceScrollbarCoroutine)
		{
			if ((Object)(object)LastNode == (Object)null || LastNode.clearPreviousText)
			{
				ExecuteScrollCoroutine(__instance, ref ___forceScrollbarCoroutine);
			}
			else
			{
				((MonoBehaviour)__instance).StartCoroutine("forceScrollbarDown");
			}
		}

		private static void ExecuteScrollCoroutine(Terminal terminal, ref Coroutine forceScrollbarCoroutine)
		{
			if (forceScrollbarCoroutine != null)
			{
				((MonoBehaviour)terminal).StopCoroutine(forceScrollbarCoroutine);
			}
			forceScrollbarCoroutine = ((MonoBehaviour)terminal).StartCoroutine("forceScrollbarUp");
		}
	}
	[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
	public static class TextPostProcessPatch
	{
		[HarmonyPrefix]
		public static void Prefix(ref string modifiedDisplayText)
		{
			modifiedDisplayText = modifiedDisplayText.TrimStart('\n', ' ');
			if (!modifiedDisplayText.EndsWith('\n'))
			{
				modifiedDisplayText += "\n";
			}
		}
	}
}
namespace LethalAPI.TerminalCommands.Models
{
	public enum AllowedCaller
	{
		None = -1,
		Player,
		Host
	}
	public class ArgumentStream
	{
		public string[] Arguments { get; }

		public int Index { get; set; }

		public bool EndOfStream => Index >= Arguments.Length;

		public ArgumentStream(string[] arguments)
		{
			Arguments = arguments;
		}

		public void Reset()
		{
			Index = 0;
		}

		public bool TryReadNext(Type type, out object value)
		{
			if (EndOfStream)
			{
				value = null;
				return false;
			}
			return StringConverter.TryConvert(Arguments[Index++], type, out value);
		}

		public bool TryReadRemaining(out string result)
		{
			if (EndOfStream)
			{
				result = null;
				return false;
			}
			result = string.Join(" ", Arguments.Skip(Index));
			return true;
		}

		public bool TryReadNext(out string value)
		{
			value = string.Empty;
			if (EndOfStream)
			{
				return false;
			}
			value = Arguments[Index++];
			return true;
		}

		public bool TryReadNext(out sbyte value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return sbyte.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out byte value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return byte.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out short value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return short.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out ushort value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return ushort.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out int value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return int.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out uint value)
		{
			value = 0u;
			if (EndOfStream)
			{
				return false;
			}
			return uint.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out long value)
		{
			value = 0L;
			if (EndOfStream)
			{
				return false;
			}
			return long.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out ulong value)
		{
			value = 0uL;
			if (EndOfStream)
			{
				return false;
			}
			return ulong.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out float value)
		{
			value = 0f;
			if (EndOfStream)
			{
				return false;
			}
			return float.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out double value)
		{
			value = 0.0;
			if (EndOfStream)
			{
				return false;
			}
			return double.TryParse(Arguments[Index++], out value);
		}
	}
	public class CommandComparer : IComparer<TerminalCommand>
	{
		public int Compare(TerminalCommand x, TerminalCommand y)
		{
			if (x.Priority > y.Priority)
			{
				return 1;
			}
			if (x.Priority < y.Priority)
			{
				return -1;
			}
			return x.ArgumentCount.CompareTo(y.ArgumentCount);
		}
	}
	public static class CommandHandler
	{
		private static readonly Regex m_SplitRegex = new Regex("[\\\"](.+?)[\\\"]|([^ ]+)", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);

		private static readonly CommandComparer m_Comparer = new CommandComparer();

		public static TerminalNode TryExecute(string command, Terminal terminal)
		{
			IEnumerable<string> source = from Match x in m_SplitRegex.Matches(command.Trim())
				select x.Value.Trim('"', ' ');
			string commandName = source.First();
			string[] arguments = source.Skip(1).ToArray();
			List<(TerminalCommand, Func<TerminalNode>)> list = new List<(TerminalCommand, Func<TerminalNode>)>();
			TerminalCommand[] array = TerminalRegistry.GetCommands(commandName).ToArray();
			foreach (TerminalCommand terminalCommand in array)
			{
				if (terminalCommand.CheckAllowed() && terminalCommand.TryCreateInvoker(arguments, terminal, out var invoker))
				{
					list.Add((terminalCommand, invoker));
				}
			}
			foreach (var item in list.OrderByDescending<(TerminalCommand, Func<TerminalNode>), TerminalCommand>(((TerminalCommand command, Func<TerminalNode> invoker) x) => x.command, m_Comparer))
			{
				TerminalNode val = item.Item2();
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	public static class DefaultStringConverters
	{
		[StringConverter]
		public static string ParseString(string input)
		{
			return input;
		}

		[StringConverter]
		public static sbyte ParseSByte(string input)
		{
			if (sbyte.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static byte ParseByte(string input)
		{
			if (byte.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static short ParseShort(string input)
		{
			if (short.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static ushort ParseUShort(string input)
		{
			if (ushort.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static int ParseInt(string input)
		{
			if (int.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static uint ParseUInt(string input)
		{
			if (uint.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static long ParseLong(string input)
		{
			if (long.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static ulong ParseULong(string input)
		{
			if (ulong.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static float ParseFloat(string input)
		{
			if (float.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static double ParseDouble(string input)
		{
			if (double.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static decimal ParseDecimal(string input)
		{
			if (decimal.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		public static PlayerControllerB ParsePlayerControllerB(string value)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				throw new ArgumentException("Game has not started");
			}
			PlayerControllerB val = null;
			if (ulong.TryParse(value, out var steamID))
			{
				val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.playerSteamId == steamID));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.playerUsername.IndexOf(value, StringComparison.InvariantCultureIgnoreCase) != -1));
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException("Failed to find player");
			}
			return val;
		}
	}
	public enum PersistType
	{
		LocalPlayer,
		Host,
		Save
	}
	public delegate object StringConversionHandler(string value);
	public static class StringConverter
	{
		private static bool m_Initialized = false;

		public static ConcurrentDictionary<Type, StringConversionHandler> StringConverters { get; } = new ConcurrentDictionary<Type, StringConversionHandler>();


		public static bool TryConvert(string value, Type type, out object result)
		{
			if (!m_Initialized)
			{
				m_Initialized = true;
				RegisterFromType(typeof(DefaultStringConverters), null, replaceExisting: false);
			}
			if (!StringConverters.TryGetValue(type, out var value2))
			{
				result = null;
				return false;
			}
			try
			{
				result = value2(value);
				return true;
			}
			catch (ArgumentException)
			{
			}
			result = null;
			return false;
		}

		public static void RegisterFrom<T>(T instance, bool replaceExisting = true) where T : class
		{
			RegisterFromType(typeof(T), instance, replaceExisting);
		}

		public static void RegisterFromType(Type type, object instance = null, bool replaceExisting = true)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo method in methods)
			{
				if (method.GetCustomAttribute<StringConverterAttribute>() == null)
				{
					continue;
				}
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(string)))
				{
					Type returnType = method.ReturnType;
					StringConversionHandler value2 = (string value) => method.Invoke(instance, new object[1] { value });
					if (replaceExisting || !StringConverters.ContainsKey(returnType))
					{
						StringConverters[returnType] = value2;
					}
				}
			}
		}
	}
	public class TerminalCommand
	{
		private ManualLogSource m_LogSource = new ManualLogSource("LethalAPI.TerminalCommands");

		public string Name { get; }

		public MethodInfo Method { get; }

		public object Instance { get; }

		public bool ClearConsole { get; }

		public int ArgumentCount { get; }

		public string Syntax { get; }

		public string Description { get; }

		public int Priority { get; }

		public TerminalCommand(string name, MethodInfo method, object instance, bool clearConsole, string syntax = null, string description = null, int priority = 0)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Name = name;
			Method = method;
			Instance = instance;
			ClearConsole = clearConsole;
			ArgumentCount = method.GetParameters().Length;
			Syntax = syntax;
			Description = description;
			Priority = priority;
		}

		public bool CheckAllowed()
		{
			foreach (AccessControlAttribute customAttribute in Method.GetCustomAttributes<AccessControlAttribute>())
			{
				if (!customAttribute.CheckAllowed())
				{
					return false;
				}
			}
			return true;
		}

		public static TerminalCommand FromMethod(MethodInfo info, object instance, string overrideName = null)
		{
			bool clearConsole = false;
			string syntax = null;
			string description = null;
			string text = overrideName;
			int priority = 0;
			TerminalCommandAttribute customAttribute = info.GetCustomAttribute<TerminalCommandAttribute>();
			if (customAttribute != null)
			{
				text = text ?? customAttribute.CommandName;
				clearConsole = customAttribute.ClearText;
			}
			CommandInfoAttribute customAttribute2 = info.GetCustomAttribute<CommandInfoAttribute>();
			if (customAttribute2 != null)
			{
				syntax = customAttribute2.Syntax;
				description = customAttribute2.Description;
			}
			CommandPriority customAttribute3 = info.GetCustomAttribute<CommandPriority>();
			if (customAttribute3 != null)
			{
				priority = customAttribute3.Priority;
			}
			return new TerminalCommand(text, info, instance, clearConsole, syntax, description, priority);
		}

		public bool TryCreateInvoker(string[] arguments, Terminal terminal, out Func<TerminalNode> invoker)
		{
			ParameterInfo[] parameters = Method.GetParameters();
			object[] values = new object[parameters.Length];
			ArgumentStream argumentStream = new ArgumentStream(arguments);
			invoker = null;
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				Type parameterType = parameterInfo.ParameterType;
				if (parameterType == typeof(Terminal))
				{
					values[i] = terminal;
				}
				else if (parameterType == typeof(ArgumentStream))
				{
					values[i] = argumentStream;
				}
				else if (parameterType == typeof(string[]))
				{
					values[i] = arguments;
				}
				else if (parameterType == typeof(string) && parameterInfo.GetCustomAttribute<RemainingTextAttribute>() != null)
				{
					if (!argumentStream.TryReadRemaining(out var result))
					{
						return false;
					}
					values[i] = result;
				}
				else
				{
					if (!argumentStream.TryReadNext(parameterType, out var value))
					{
						return false;
					}
					values[i] = value;
				}
			}
			argumentStream.Reset();
			invoker = () => ExecuteCommand(values);
			return true;
		}

		private TerminalNode ExecuteCommand(object[] arguments)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			object obj;
			try
			{
				obj = Method.Invoke(Instance, arguments);
			}
			catch (Exception ex)
			{
				m_LogSource.LogError((object)("Error caught while invoking command hander: " + ex.Message));
				m_LogSource.LogError((object)ex.StackTrace);
				return null;
			}
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			if (!typeof(TerminalNode).IsAssignableFrom(type))
			{
				TerminalNode obj2 = ScriptableObject.CreateInstance<TerminalNode>();
				obj2.displayText = obj.ToString() + "\n";
				obj2.clearPreviousText = ClearConsole;
				return obj2;
			}
			return (TerminalNode)obj;
		}
	}
	public class TerminalModRegistry
	{
		public List<TerminalCommand> Commands { get; } = new List<TerminalCommand>();


		public T RegisterFrom<T>() where T : class, new()
		{
			return RegisterFrom(new T());
		}

		public T RegisterFrom<T>(T instance) where T : class
		{
			foreach (MethodInfo commandMethod in TerminalRegistry.GetCommandMethods<T>())
			{
				TerminalCommand terminalCommand = TerminalCommand.FromMethod(commandMethod, instance);
				TerminalRegistry.RegisterCommand(terminalCommand);
				lock (Commands)
				{
					Commands.Add(terminalCommand);
				}
			}
			StringConverter.RegisterFrom(instance);
			return instance;
		}

		public void Deregister()
		{
			if (Commands != null)
			{
				for (int i = 0; i < Commands.Count; i++)
				{
					TerminalRegistry.Deregister(Commands[i]);
				}
			}
		}
	}
	public class TerminalRegistry
	{
		private static readonly ConcurrentDictionary<string, List<TerminalCommand>> m_RegisteredCommands = new ConcurrentDictionary<string, List<TerminalCommand>>(StringComparer.InvariantCultureIgnoreCase);

		public static TerminalModRegistry RegisterFrom<T>(T instance) where T : class
		{
			TerminalModRegistry terminalModRegistry = new TerminalModRegistry();
			foreach (MethodInfo commandMethod in GetCommandMethods<T>())
			{
				TerminalCommand terminalCommand = TerminalCommand.FromMethod(commandMethod, instance);
				RegisterCommand(terminalCommand);
				terminalModRegistry.Commands.Add(terminalCommand);
			}
			StringConverter.RegisterFrom(instance);
			return terminalModRegistry;
		}

		public static TerminalModRegistry CreateTerminalRegistry()
		{
			return new TerminalModRegistry();
		}

		public static void RegisterCommand(TerminalCommand command)
		{
			if (!m_RegisteredCommands.TryGetValue(command.Name, out var value))
			{
				value = new List<TerminalCommand>();
				m_RegisteredCommands[command.Name] = value;
			}
			lock (value)
			{
				value.Add(command);
			}
		}

		public static void Deregister(TerminalCommand command)
		{
			if (!m_RegisteredCommands.TryGetValue(command.Name, out var value))
			{
				return;
			}
			lock (value)
			{
				value.Remove(command);
			}
		}

		public static IReadOnlyList<TerminalCommand> GetCommands(string commandName)
		{
			if (m_RegisteredCommands.TryGetValue(commandName, out var value))
			{
				return value;
			}
			return new List<TerminalCommand>();
		}

		public static IEnumerable<TerminalCommand> EnumerateCommands(string name)
		{
			if (!m_RegisteredCommands.TryGetValue(name, out var value))
			{
				return Enumerable.Empty<TerminalCommand>();
			}
			return value;
		}

		public static IEnumerable<TerminalCommand> EnumerateCommands()
		{
			string[] keys = m_RegisteredCommands.Keys.ToArray();
			for (int i = 0; i < keys.Length; i++)
			{
				List<TerminalCommand> overloads = m_RegisteredCommands[keys[i]];
				for (int c = 0; c < overloads.Count; c++)
				{
					yield return overloads[c];
				}
			}
		}

		public static IEnumerable<MethodInfo> GetCommandMethods<T>()
		{
			MethodInfo[] methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.GetCustomAttribute<TerminalCommandAttribute>() != null)
				{
					yield return methodInfo;
				}
			}
		}
	}
}
namespace LethalAPI.TerminalCommands.Configs
{
	[ConfigGroup("Terminal", "Configure the behavior of the terminal")]
	public class TerminalConfig
	{
		[TerminalConfig("Enables/Disables terminal verb commands", null)]
		[ConfigPersist(PersistType.LocalPlayer, null)]
		public bool VerbsEnabled { get; set; }

		[TerminalConfig("Specifies if the Confirm/Deny pop-up should be shown", null)]
		[ConfigPersist(PersistType.LocalPlayer, null)]
		public bool AutoConfirm { get; set; }
	}
}
namespace LethalAPI.TerminalCommands.Commands
{
	public class CommandInfoCommands
	{
		[TerminalCommand("Other", true)]
		public string CommandList()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Other commands:");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">VIEW MONITOR");
			stringBuilder.AppendLine("To toggle on/off the main monitor's map cam");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">SWITCH {RADAR}");
			stringBuilder.AppendLine("To switch the player view on the main monitor");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">PING [Radar booster name]");
			stringBuilder.AppendLine("To switch the player view on the main monitor");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">SCAN");
			stringBuilder.AppendLine("To scan for the number of items left on the current planet");
			stringBuilder.AppendLine();
			foreach (TerminalCommand item in TerminalRegistry.EnumerateCommands())
			{
				if (item.Description != null && item.CheckAllowed())
				{
					stringBuilder.AppendLine(">" + item.Name.ToUpper() + " " + item.Syntax?.ToUpper());
					stringBuilder.AppendLine(item.Description);
					stringBuilder.AppendLine();
				}
			}
			return stringBuilder.ToString();
		}

		[TerminalCommand("Help", false)]
		[CommandInfo("Shows further information about a command", "[Command]")]
		public string HelpCommand(string name)
		{
			StringBuilder stringBuilder = new StringBuilder();
			TerminalCommand[] array = TerminalRegistry.EnumerateCommands(name).ToArray();
			if (array.Length == 0)
			{
				return "Unknown command: '" + name + "'";
			}
			TerminalCommand[] array2 = array;
			foreach (TerminalCommand terminalCommand in array2)
			{
				stringBuilder.AppendLine(">" + terminalCommand.Name.ToUpper() + " " + terminalCommand.Syntax?.ToUpper());
				stringBuilder.AppendLine(terminalCommand.Description);
				if (!terminalCommand.CheckAllowed())
				{
					stringBuilder.AppendLine("[Host Only]");
				}
				stringBuilder.AppendLine();
			}
			return stringBuilder.ToString();
		}
	}
}
namespace LethalAPI.TerminalCommands.Attributes
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
	public abstract class AccessControlAttribute : Attribute
	{
		public abstract bool CheckAllowed();
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
	public class AllowedCallerAttribute : AccessControlAttribute
	{
		public AllowedCaller Caller { get; }

		public AllowedCallerAttribute(AllowedCaller caller)
		{
			Caller = caller;
		}

		public override bool CheckAllowed()
		{
			switch (Caller)
			{
			case AllowedCaller.None:
				return false;
			case AllowedCaller.Player:
				return true;
			case AllowedCaller.Host:
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return false;
				}
				return ((NetworkBehaviour)StartOfRound.Instance).IsHost;
			default:
				return true;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
	public class CommandInfoAttribute : Attribute
	{
		public string Syntax { get; }

		public string Description { get; }

		public CommandInfoAttribute(string description, string syntax = "")
		{
			Syntax = syntax;
			Description = description;
		}
	}
	public sealed class CommandPriority : Attribute
	{
		public int Priority { get; }

		public CommandPriority(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public sealed class ConfigGroupAttribute : Attribute
	{
		public string Name { get; }

		public string Description { get; }

		public ConfigGroupAttribute(string name, string description)
		{
			Name = name;
			Description = description;
		}
	}
	public class ConfigPersistAttribute : Attribute
	{
		public PersistType PersistType { get; }

		public string ConfigPath { get; }

		public ConfigPersistAttribute(PersistType persistType, string configPath = null)
		{
			PersistType = persistType;
			ConfigPath = configPath;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	public sealed class RemainingTextAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method)]
	public sealed class StringConverterAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
	public class TerminalCommandAttribute : Attribute
	{
		public string CommandName { get; }

		public bool ClearText { get; }

		public TerminalCommandAttribute(string name, bool clearText = false)
		{
			CommandName = name;
			ClearText = clearText;
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	public class TerminalConfigAttribute : Attribute
	{
		public string Name { get; }

		public string Description { get; }

		public TerminalConfigAttribute(string description, string name = null)
		{
			Name = name;
			Description = description;
		}
	}
}

BepInEx/plugins/LethalMissions.dll

Decompiled 8 months 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 System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalAPI.LibTerminal;
using LethalAPI.LibTerminal.Attributes;
using LethalAPI.LibTerminal.Models;
using LethalMissions.DefaultData;
using LethalMissions.Networking;
using LethalMissions.Patches;
using LethalMissions.Scripts;
using LethalMissions.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("LethalMissions")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod that adds missions to the game.")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6+e8505ca0796b06210bb9d91a86d745326e973688")]
[assembly: AssemblyProduct("LethalMissions")]
[assembly: AssemblyTitle("LethalMissions")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/valentin-marquez/LethalMissions")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalMissions
{
	public static class Assets
	{
		public static AssetBundle MainAssetBundle;

		public static void PopulateAssets(string streamName)
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(streamName))
				{
					MainAssetBundle = AssetBundle.LoadFromStream(stream);
				}
			}
		}
	}
	[BepInPlugin("LethalMissions", "LethalMissions", "1.0.6")]
	public class Plugin : BaseUnityPlugin
	{
		private const string ConfigFileName = "LethalMissions.cfg";

		private TerminalModRegistry commands;

		public static ManualLogSource LoggerInstance { get; private set; }

		public static Configuration Config { get; private set; }

		public static MissionManager MissionManager { get; private set; }

		private void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			LoggerInstance = ((BaseUnityPlugin)this).Logger;
			LoggerInstance.LogInfo((object)"Plugin LethalMissions is loaded!");
			ConfigFile config = new ConfigFile(Path.Combine(Paths.ConfigPath, "LethalMissions.cfg"), true);
			Config = new Configuration(config);
			LoggerInstance.LogInfo((object)("Loading missions for language: " + Config.LanguageCode.Value));
			MissionManager = new MissionManager();
			Harmony val = new Harmony("LethalMissions");
			val.PatchAll(typeof(DeadBodyInfoPatch));
			val.PatchAll(typeof(EnemyAIPatch));
			val.PatchAll(typeof(HUDManagerPatch));
			val.PatchAll(typeof(PlayerControllerBPatch));
			val.PatchAll(typeof(RoundManagerPatch));
			val.PatchAll(typeof(StartOfRoundPatch));
			val.PatchAll(typeof(NetworkObjectManager));
			Assets.PopulateAssets("LethalMissions.asset");
			if (Config.LanguageCode.Value == "en")
			{
				commands = TerminalRegistry.RegisterFrom<EnglishTerminalCommands>(new EnglishTerminalCommands());
			}
			else if (Config.LanguageCode.Value == "es")
			{
				commands = TerminalRegistry.RegisterFrom<SpanishTerminalCommands>(new SpanishTerminalCommands());
			}
			NetcodeWeaver();
		}

		private void NetcodeWeaver()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalMissions";

		public const string PLUGIN_NAME = "LethalMissions";

		public const string PLUGIN_VERSION = "1.0.6";
	}
}
namespace LethalMissions.Scripts
{
	public class Configuration
	{
		public ConfigEntry<string> LanguageCode { get; set; }

		public ConfigEntry<int> MaxMissions { get; set; }

		public string TranslationFolderPath { get; set; }

		public Configuration(ConfigFile config)
		{
			LanguageCode = config.Bind<string>("General", "LanguageCode", "en", "The language code for translations (e.g., en for English, es for Spanish).");
			MaxMissions = config.Bind<int>("General", "MaxMissions", 2, "The maximum number of moon missions to start.");
		}
	}
	public enum MissionStatus
	{
		Incomplete,
		Complete
	}
	public enum MissionType
	{
		RecoverCrewmateBody,
		LightningRod,
		WitnessCrewmateDeath,
		ObtainHoneycomb,
		SurviveCrewmates,
		UseRandomTeleporter,
		OutOfTimeLeaveBeforeCertainHour,
		KillMonster,
		ObtainGenerator,
		NoMissions
	}
	public class Mission
	{
		public string Name { get; set; }

		public string Objective { get; set; }

		public MissionStatus Status { get; set; }

		public MissionType Type { get; set; }

		public int Reward { get; set; }

		public int? LeaveTime { get; set; }

		public int? SurviveCrewmates { get; set; }

		public Mission(string missionName, string missionObjective, MissionType missionType, int reward, int? leaveTime = null, int? surviveCrewmates = null)
		{
			Name = missionName;
			Objective = missionObjective;
			Status = MissionStatus.Incomplete;
			Type = missionType;
			Reward = reward;
			LeaveTime = leaveTime;
			SurviveCrewmates = surviveCrewmates;
			base..ctor();
		}
	}
	public class MissionManager : MonoBehaviour
	{
		private List<Mission> Allmissions = new List<Mission>();

		private List<Mission> Currentmissions = new List<Mission>();

		public MissionManager()
		{
			Allmissions = (from m in DefaultMissions.Missions
				where m.LanguageCode == Plugin.Config.LanguageCode.Value
				select new Mission(m.MissionName, m.MissionObjective, m.MissionType, m.MissionReward)).ToList();
			Plugin.LoggerInstance.LogInfo((object)$"Loaded {Allmissions.Count} missions for language {Plugin.Config.LanguageCode.Value}");
		}

		public static int GenerateRandomLeaveTime()
		{
			return new Random().Next(6, 11);
		}

		public static int GenerateRandomSurviveCrewmates()
		{
			int num = Object.FindObjectsOfType<PlayerControllerB>().Count((PlayerControllerB player) => player.isInHangarShipRoom && !player.isPlayerDead);
			Plugin.LoggerInstance.LogInfo((object)$"JUGADORES VIVOS: {num}");
			if (num == 1)
			{
				return 1;
			}
			return (int)((double)num * 0.75);
		}

		public void GenerateMissions(int n)
		{
			Plugin.LoggerInstance.LogInfo((object)$"Generating {n} missions...");
			if (n > Allmissions.Count)
			{
				n = Allmissions.Count;
				Plugin.LoggerInstance.LogInfo((object)"Requested number of missions is greater than available missions. Generating all available missions.");
			}
			if (n < 1)
			{
				Plugin.LoggerInstance.LogInfo((object)"No missions to generate.");
				return;
			}
			Currentmissions.Clear();
			Plugin.LoggerInstance.LogInfo((object)"Cleared current missions.");
			Allmissions.Shuffle();
			Plugin.LoggerInstance.LogInfo((object)"Shuffled all missions.");
			for (int i = 0; i < n; i++)
			{
				Mission mission = Allmissions[i];
				if (mission.Type == MissionType.OutOfTimeLeaveBeforeCertainHour)
				{
					mission.LeaveTime = GenerateRandomLeaveTime();
					Plugin.LoggerInstance.LogInfo((object)$"Generated leave time for mission {mission.Name}: {mission.LeaveTime}");
				}
				else if (mission.Type == MissionType.SurviveCrewmates)
				{
					mission.SurviveCrewmates = GenerateRandomSurviveCrewmates();
					Plugin.LoggerInstance.LogInfo((object)$"Generated survive crewmates for mission {mission.Name}: {mission.SurviveCrewmates}");
				}
				Currentmissions.Add(mission);
			}
			SyncMissionsServer();
			Plugin.LoggerInstance.LogInfo((object)"Synced missions.");
		}

		public string ShowMissionOverview()
		{
			StringBuilder stringBuilder = new StringBuilder();
			string value = Plugin.Config.LanguageCode.Value;
			stringBuilder.AppendLine("LethalMissions\n");
			if (Currentmissions.Count == 0)
			{
				stringBuilder.AppendLine(StringUtilities.GetNoMissionsMessage(value));
			}
			else
			{
				foreach (Mission currentmission in Currentmissions)
				{
					if (currentmission.Type == MissionType.OutOfTimeLeaveBeforeCertainHour)
					{
						stringBuilder.AppendLine(StringUtilities.GetName(value) + string.Format(currentmission.Name, currentmission.LeaveTime + " PM"));
						stringBuilder.AppendLine(StringUtilities.GetObjective(value) + string.Format(currentmission.Objective, currentmission.LeaveTime + " PM"));
					}
					else if (currentmission.Type == MissionType.SurviveCrewmates)
					{
						stringBuilder.AppendLine(StringUtilities.GetName(value) + currentmission.Name);
						stringBuilder.AppendLine(StringUtilities.GetObjective(value) + string.Format(currentmission.Objective, currentmission.SurviveCrewmates));
					}
					else
					{
						stringBuilder.AppendLine(StringUtilities.GetName(value) + currentmission.Name);
						stringBuilder.AppendLine(StringUtilities.GetObjective(value) + currentmission.Objective);
					}
					stringBuilder.AppendLine($"{StringUtilities.GetStatus(value)}{currentmission.Status}");
					stringBuilder.AppendLine($"{StringUtilities.GetReward(value)}{currentmission.Reward}");
					stringBuilder.AppendLine("-----------------------------");
				}
			}
			return stringBuilder.ToString();
		}

		public void RemoveActiveMissions()
		{
			Currentmissions.Clear();
			SyncMissionsServer();
			Plugin.LoggerInstance.LogInfo((object)"Cleared all active missions");
		}

		public List<Mission> GetActiveMissions()
		{
			return Currentmissions;
		}

		public void CompleteMission(MissionType missionType)
		{
			Mission mission = Currentmissions.FirstOrDefault((Mission m) => m.Type == missionType);
			if (mission != null)
			{
				mission.Status = MissionStatus.Complete;
				Plugin.LoggerInstance.LogInfo((object)$"Marked mission of type {missionType} as complete");
				SyncMissionsServer();
			}
		}

		public void IncompleteMission(MissionType missionType)
		{
			Mission mission = Currentmissions.FirstOrDefault((Mission m) => m.Type == missionType);
			if (mission != null)
			{
				mission.Status = MissionStatus.Incomplete;
				SyncMissionsServer();
				Plugin.LoggerInstance.LogInfo((object)$"Marked mission of type {missionType} as incomplete");
			}
		}

		private void SyncMissionsServer()
		{
			if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
			{
				return;
			}
			if (Currentmissions != null)
			{
				string text = JsonConvert.SerializeObject((object)Currentmissions);
				Plugin.LoggerInstance.LogInfo((object)("Syncing missions Host: " + text));
				if ((Object)(object)NetworkHandler.Instance != (Object)null)
				{
					NetworkHandler.Instance.SyncMissionsServerRpc(text);
				}
				else
				{
					Plugin.LoggerInstance.LogError((object)"SyncMissionsServer - NetworkHandler.Instance is null");
				}
			}
			else
			{
				Plugin.LoggerInstance.LogError((object)"Currentmissions is null");
			}
		}

		public void RequestMissionsClient()
		{
			if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsHost)
			{
				if ((Object)(object)NetworkHandler.Instance != (Object)null)
				{
					NetworkHandler.Instance.RequestMissionsServerRpc(NetworkManager.Singleton.LocalClientId);
				}
				else
				{
					Plugin.LoggerInstance.LogError((object)"RequestMissionsClient - NetworkHandler.Instance is null");
				}
			}
		}

		internal void SyncMissions(string serializedMissions)
		{
			Plugin.LoggerInstance.LogInfo((object)("Syncing missions Client: " + serializedMissions));
			List<Mission> collection = JsonConvert.DeserializeObject<List<Mission>>(serializedMissions);
			Currentmissions.Clear();
			Currentmissions.AddRange(collection);
		}

		public void RequestMissions()
		{
			if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsHost)
			{
				if ((Object)(object)NetworkHandler.Instance != (Object)null)
				{
					NetworkHandler.Instance.RequestMissionsServerRpc(NetworkManager.Singleton.LocalClientId);
				}
				else
				{
					Plugin.LoggerInstance.LogError((object)"NetworkHandler.Instance is null");
				}
			}
		}

		public bool IsMissionInCurrentMissions(MissionType type)
		{
			return Currentmissions.Any((Mission m) => m.Type == type);
		}

		public int GetMissionLeaveTime(MissionType type)
		{
			return Currentmissions.FirstOrDefault((Mission m) => m.Type == type).LeaveTime.Value;
		}

		public int GetCreditsEarned()
		{
			return Currentmissions.Where((Mission m) => m.Status == MissionStatus.Complete).Sum((Mission m) => m.Reward);
		}

		public List<Mission> GetCompletedMissions()
		{
			return Currentmissions.Where((Mission m) => m.Status == MissionStatus.Complete).ToList();
		}

		public int GetSurviveCrewmates()
		{
			return Currentmissions.FirstOrDefault((Mission m) => m.Type == MissionType.SurviveCrewmates).SurviveCrewmates.Value;
		}
	}
	public interface ITerminalCommands
	{
		string MissionsCommand();
	}
	internal class EnglishTerminalCommands : ITerminalCommands
	{
		[TerminalCommand("Missions", true)]
		[CommandInfo("Show all Lethal Missions", "")]
		public string MissionsCommand()
		{
			return Plugin.MissionManager.ShowMissionOverview();
		}
	}
	internal class SpanishTerminalCommands : ITerminalCommands
	{
		[TerminalCommand("Misiones", true)]
		[CommandInfo("Muestra todas las Misiones Letales", "")]
		public string MissionsCommand()
		{
			return Plugin.MissionManager.ShowMissionOverview();
		}
	}
}
namespace LethalMissions.Patches
{
	[HarmonyPatch(typeof(DeadBodyInfo))]
	internal class DeadBodyInfoPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("DetectIfSeenByLocalPlayer")]
		private static void OnDetect()
		{
			Plugin.MissionManager.CompleteMission(MissionType.WitnessCrewmateDeath);
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	public class EnemyAIPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("KillEnemy")]
		public static void OnEnemyKilled(EnemyAI __instance)
		{
			if (__instance.isEnemyDead)
			{
				Plugin.MissionManager.CompleteMission(MissionType.KillMonster);
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal class HUDManagerPatch
	{
		public static int Hour { get; private set; }

		public static bool IsPM { get; private set; }

		[HarmonyPostfix]
		[HarmonyPatch("SetClock")]
		private static void OnSetClock(float timeNormalized, float numberOfHours)
		{
			int num = (int)(timeNormalized * (60f * numberOfHours)) + 360;
			int num2 = (int)Mathf.Floor((float)(num / 60));
			if (num2 >= 12)
			{
				num2 %= 12;
				IsPM = true;
			}
			else
			{
				IsPM = false;
			}
			Plugin.LoggerInstance.LogInfo((object)$"Current Time: {num2}, Es PM: {IsPM}");
		}
	}
	public class NetworkObjectManager
	{
		private static GameObject networkPrefab;

		private static GameObject networkHandlerHost;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void OnStart()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				networkPrefab = (GameObject)Assets.MainAssetBundle.LoadAsset("LethalMissionsNetworkHandler");
				networkPrefab.AddComponent<NetworkHandler>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				Plugin.LoggerInstance.LogInfo((object)"LethalMissions:  NetworkHandler prefab added to NetworkManager");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				networkHandlerHost = Object.Instantiate<GameObject>(networkPrefab);
				networkHandlerHost.GetComponent<NetworkObject>().Spawn(true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		private static void DestroyNetworkHandler()
		{
			try
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					Plugin.LoggerInstance.LogInfo((object)"LethalMissions:  Destroying NetworkHandler on Host");
					Object.Destroy((Object)(object)networkHandlerHost);
					networkHandlerHost = null;
				}
			}
			catch
			{
				Plugin.LoggerInstance.LogError((object)"LethalMissions:  Failed to destroy NetworkHandler on Host");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch : NetworkBehaviour
	{
		[HarmonyPrefix]
		[HarmonyPatch("KillPlayer")]
		private static void OnKillPlayer(Vector3 bodyVelocity, bool spawnBody = true, CauseOfDeath causeOfDeath = 0, int deathAnimation = 0)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			//IL_0043: Invalid comparison between I4 and Unknown
			Plugin.LoggerInstance.LogWarning((object)$"OnKillPlayerServerRpc called. spawnbody: {spawnBody}, bodyvelocity: {bodyVelocity}, causeofdeath: {causeOfDeath}, deathanimation: {deathAnimation}");
			if (11 == (int)causeOfDeath)
			{
				Plugin.MissionManager.CompleteMission(MissionType.LightningRod);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		private static void OnConnectClientToPlayerObject()
		{
			if (!NetworkManager.Singleton.IsHost || !NetworkManager.Singleton.IsServer)
			{
				Plugin.LoggerInstance.LogWarning((object)"OnConnectClientToPlayerObject called.");
				Plugin.MissionManager.RequestMissions();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetItemInElevator")]
		private static void OnSetItemInElevator(bool droppedInShipRoom, bool droppedInElevator, GrabbableObject gObject)
		{
			if (gObject.itemProperties.itemId == 1531 && droppedInShipRoom)
			{
				Plugin.MissionManager.CompleteMission(MissionType.ObtainHoneycomb);
			}
			else if (gObject.itemProperties.itemId == 3 && droppedInShipRoom)
			{
				Plugin.MissionManager.CompleteMission(MissionType.ObtainGenerator);
			}
			else if (gObject is RagdollGrabbableObject && droppedInShipRoom)
			{
				Plugin.MissionManager.CompleteMission(MissionType.RecoverCrewmateBody);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "PlayerControllerBPatch";
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public class RoundManagerPatch : NetworkBehaviour
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static void OnAwake()
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Plugin.MissionManager.RemoveActiveMissions();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GenerateNewLevelClientRpc")]
		private static void OnGameStart()
		{
			Plugin.LoggerInstance.LogInfo((object)"Start Game - starting Game");
			if (StartOfRound.Instance.currentLevelID != 3)
			{
				if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
				{
					Plugin.LoggerInstance.LogInfo((object)"Host or server -  Generating missions");
					Plugin.MissionManager.GenerateMissions(Plugin.Config.MaxMissions.Value);
				}
				else
				{
					Plugin.LoggerInstance.LogInfo((object)"Client - Requesting missions");
					Plugin.MissionManager.RequestMissions();
				}
				HUDManager.Instance.DisplayTip("LethalMissions", StringUtilities.GetNewMissionsAvailableMessage(Plugin.Config.LanguageCode.Value), true, false, "LC_Tip1");
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "RoundManagerPatch";
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch : NetworkBehaviour
	{
		[HarmonyPostfix]
		[HarmonyPatch("ShipLeave")]
		private static void OnEndGame()
		{
			if (StartOfRound.Instance.currentLevel.levelID == 3)
			{
				return;
			}
			Plugin.LoggerInstance.LogInfo((object)"End Game calculating rewards...");
			if (Plugin.MissionManager.IsMissionInCurrentMissions(MissionType.SurviveCrewmates))
			{
				List<PlayerControllerB> source = Object.FindObjectsOfType<PlayerControllerB>().ToList();
				int num = source.Count((PlayerControllerB player) => player.isInHangarShipRoom && !player.isPlayerDead);
				Plugin.LoggerInstance.LogInfo((object)$"Living players: {num}");
				if (num >= Plugin.MissionManager.GetSurviveCrewmates())
				{
					Plugin.MissionManager.CompleteMission(MissionType.SurviveCrewmates);
					Plugin.LoggerInstance.LogInfo((object)$"Completed mission {MissionType.SurviveCrewmates}");
				}
				else
				{
					Plugin.LoggerInstance.LogInfo((object)$"Mission {MissionType.SurviveCrewmates} not completed");
				}
			}
			if (Plugin.MissionManager.IsMissionInCurrentMissions(MissionType.OutOfTimeLeaveBeforeCertainHour))
			{
				int missionLeaveTime = Plugin.MissionManager.GetMissionLeaveTime(MissionType.OutOfTimeLeaveBeforeCertainHour);
				if (!HUDManagerPatch.IsPM || (HUDManagerPatch.IsPM && HUDManagerPatch.Hour < missionLeaveTime))
				{
					Plugin.MissionManager.CompleteMission(MissionType.OutOfTimeLeaveBeforeCertainHour);
					Plugin.LoggerInstance.LogInfo((object)$"Completed mission {MissionType.OutOfTimeLeaveBeforeCertainHour}");
				}
				else
				{
					Plugin.LoggerInstance.LogInfo((object)$"Mission {MissionType.OutOfTimeLeaveBeforeCertainHour} not completed");
				}
			}
			CalculateRewards();
			Plugin.MissionManager.RemoveActiveMissions();
		}

		public static void CalculateRewards()
		{
			Terminal val = Object.FindObjectOfType<Terminal>();
			int groupCredits = val.groupCredits;
			int creditsEarned = Plugin.MissionManager.GetCreditsEarned();
			int groupCredits2 = groupCredits + creditsEarned;
			val.groupCredits = groupCredits2;
			DisplayMissionCompletion(creditsEarned);
		}

		public static void DisplayMissionCompletion(int creditsEarned)
		{
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			Plugin.LoggerInstance.LogInfo((object)"Displaying mission completion...");
			List<Mission> completedMissions = Plugin.MissionManager.GetCompletedMissions();
			Plugin.LoggerInstance.LogInfo((object)$"Number of completed missions: {completedMissions.Count}");
			string text = ((completedMissions.Count == 0) ? StringUtilities.GetNoCompletedMissionsMessage(Plugin.Config.LanguageCode.Value) : StringUtilities.GetCompletedMissionsCountMessage(Plugin.Config.LanguageCode.Value, completedMissions.Count));
			GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/SpecialHUDGraphics/RewardsScreen/Container/Container2/Header");
			((TMP_Text)val.GetComponent<TextMeshProUGUI>()).fontSize = 26f;
			((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = "Lethal Missions";
			((TMP_Text)HUDManager.Instance.moneyRewardsListText).fontSize = ((TMP_Text)HUDManager.Instance.moneyRewardsListText).fontSize / 2f;
			((TMP_Text)HUDManager.Instance.moneyRewardsListText).text = text;
			((TMP_Text)HUDManager.Instance.moneyRewardsTotalText).text = $"TOTAL: ${creditsEarned}";
			HUDManager.Instance.rewardsScrollbar.value = 1f;
			if (Plugin.Config.MaxMissions.Value > 8)
			{
				Type typeFromHandle = typeof(HUDManager);
				FieldInfo field = typeFromHandle.GetField("scrollRewardTextCoroutine", BindingFlags.Instance | BindingFlags.NonPublic);
				HUDManager instance = HUDManager.Instance;
				Coroutine val2 = (Coroutine)field.GetValue(instance);
				if (val2 != null)
				{
					((MonoBehaviour)instance).StopCoroutine(val2);
					Plugin.LoggerInstance.LogInfo((object)"Stopped existing scrollRewardTextCoroutine");
				}
				field.SetValue(instance, ((MonoBehaviour)instance).StartCoroutine(ScrollRewardsListText()));
				Plugin.LoggerInstance.LogInfo((object)"Started new scrollRewardTextCoroutine");
			}
			((MonoBehaviour)HUDManager.Instance).StartCoroutine(ShowRewardsAndRestoreHeader(val));
			Plugin.LoggerInstance.LogInfo((object)"Started ShowRewardsAndRestoreHeader coroutine");
		}

		private static IEnumerator ShowRewardsAndRestoreHeader(GameObject header)
		{
			HUDManager.Instance.moneyRewardsAnimator.SetTrigger("showRewards");
			Plugin.LoggerInstance.LogInfo((object)"Triggered showRewards animation");
			yield return (object)new WaitForSeconds(10f);
			((TMP_Text)HUDManager.Instance.moneyRewardsListText).fontSize = ((TMP_Text)HUDManager.Instance.moneyRewardsListText).fontSize * 2f;
			((TMP_Text)header.GetComponent<TextMeshProUGUI>()).fontSize = 36f;
			((TMP_Text)header.GetComponent<TextMeshProUGUI>()).text = "PAYCHECK!";
			Plugin.LoggerInstance.LogInfo((object)"Restored header text and font size");
		}

		private static IEnumerator ScrollRewardsListText()
		{
			yield return (object)new WaitForSeconds(1.5f);
			Plugin.LoggerInstance.LogInfo((object)"Waited 1.5 seconds");
			float num = 3f;
			while (num >= 0f)
			{
				num -= Time.deltaTime;
				Scrollbar rewardsScrollbar = HUDManager.Instance.rewardsScrollbar;
				rewardsScrollbar.value -= Time.deltaTime / num;
				Plugin.LoggerInstance.LogInfo((object)$"Updated rewardsScrollbar value to {HUDManager.Instance.rewardsScrollbar.value}");
			}
			Plugin.LoggerInstance.LogInfo((object)"Finished scrolling rewards list text");
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "StartOfRoundPatch";
		}
	}
}
namespace LethalMissions.Networking
{
	public class NetworkHandler : NetworkBehaviour
	{
		private string currentSerializedMissions;

		public static NetworkHandler Instance { get; private set; }

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
		}

		private void Awake()
		{
			Instance = this;
		}

		[ServerRpc(RequireOwnership = false)]
		public void SyncMissionsServerRpc(string serializedMissions)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4080571439u, val, (RpcDelivery)0);
				bool flag = serializedMissions != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(serializedMissions, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4080571439u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				Debug.Log((object)("LethalMissions - SyncMissionsServerRpc: " + serializedMissions));
				currentSerializedMissions = serializedMissions;
				SyncMissionsClientRpc(serializedMissions);
			}
		}

		[ClientRpc]
		public void SyncMissionsClientRpc(string serializedMissions)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1031828279u, val, (RpcDelivery)0);
				bool flag = serializedMissions != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(serializedMissions, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1031828279u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				Debug.Log((object)("LethalMissions - SyncMissionsClientRpc: " + serializedMissions));
				currentSerializedMissions = serializedMissions;
				Plugin.MissionManager.SyncMissions(serializedMissions);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void RequestMissionsServerRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(293238159u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, clientId);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 293238159u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Debug.Log((object)$"LethalMissions - RequestMissionsServerRpc: {clientId}");
					SendMissionsClientRpc(currentSerializedMissions, clientId);
				}
			}
		}

		[ClientRpc]
		public void SendMissionsClientRpc(string serializedMissions, ulong targetClientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3600468003u, val, (RpcDelivery)0);
				bool flag = serializedMissions != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(serializedMissions, false);
				}
				BytePacker.WriteValueBitPacked(val2, targetClientId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3600468003u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && NetworkManager.Singleton.LocalClientId == targetClientId)
			{
				Debug.Log((object)("LethalMissions - SendMissionsClientRpc: " + serializedMissions));
				Plugin.MissionManager.SyncMissions(serializedMissions);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_NetworkHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(4080571439u, new RpcReceiveHandler(__rpc_handler_4080571439));
			NetworkManager.__rpc_func_table.Add(1031828279u, new RpcReceiveHandler(__rpc_handler_1031828279));
			NetworkManager.__rpc_func_table.Add(293238159u, new RpcReceiveHandler(__rpc_handler_293238159));
			NetworkManager.__rpc_func_table.Add(3600468003u, new RpcReceiveHandler(__rpc_handler_3600468003));
		}

		private static void __rpc_handler_4080571439(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string serializedMissions = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref serializedMissions, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).SyncMissionsServerRpc(serializedMissions);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1031828279(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string serializedMissions = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref serializedMissions, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).SyncMissionsClientRpc(serializedMissions);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_293238159(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).RequestMissionsServerRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3600468003(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string serializedMissions = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref serializedMissions, false);
				}
				ulong targetClientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((NetworkHandler)(object)target).SendMissionsClientRpc(serializedMissions, targetClientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "NetworkHandler";
		}
	}
}
namespace LethalMissions.Utils
{
	public static class Utils
	{
		private static class ThreadSafeRandom
		{
			[ThreadStatic]
			private static Random Local;

			public static Random ThisThreadsRandom => Local ?? (Local = new Random(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId));
		}

		public static void Shuffle<T>(this IList<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = ThreadSafeRandom.ThisThreadsRandom.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}
	}
}
namespace LethalMissions.DefaultData
{
	public static class DefaultMissions
	{
		public static List<DefaultMissionData> Missions { get; private set; }

		static DefaultMissions()
		{
			Missions = new List<DefaultMissionData>
			{
				new DefaultMissionData(MissionType.OutOfTimeLeaveBeforeCertainHour, "Escape before {0}", "Don't stay on the moon after {0}! It's a dangerous place!", "en", 30),
				new DefaultMissionData(MissionType.LightningRod, "Attracting Lightning", "Become the human lightning rod, stop a lightning with style", "en", 100),
				new DefaultMissionData(MissionType.WitnessCrewmateDeath, "Witness a Celestial Event", "Witness the dramatic farewell of a fellow crewmate", "en", 40),
				new DefaultMissionData(MissionType.RecoverCrewmateBody, "Retrieve Your Pal's Corpse", "Because being a hero also means playing space undertaker", "en", 20),
				new DefaultMissionData(MissionType.ObtainHoneycomb, "Get a beehive!", "Because even in space, we all need some honey and laughter", "en", 80),
				new DefaultMissionData(MissionType.SurviveCrewmates, "Preserve the Group's Life", "Make sure at least {0} crewmates survive the space odyssey!", "en", 100),
				new DefaultMissionData(MissionType.KillMonster, "Defeat the Monster", "Embark on a daring mission to eliminate a menacing creature", "en", 50),
				new DefaultMissionData(MissionType.ObtainGenerator, "Obtaining the Apparatus", "Obtain the Factory Generator", "en", 50),
				new DefaultMissionData(MissionType.OutOfTimeLeaveBeforeCertainHour, "Escapa antes de las {0}", "¡No te quedes en la luna después de las {0}! ¡Es un lugar peligroso!", "es", 30),
				new DefaultMissionData(MissionType.LightningRod, "Atrayendo rayos", "Conviértete en el pararrayos humano, detén un rayo con estilo", "es", 100),
				new DefaultMissionData(MissionType.WitnessCrewmateDeath, "Atestigua un suceso celestial", "Observa el dramático adiós de un compañero de la nave", "es", 40),
				new DefaultMissionData(MissionType.RecoverCrewmateBody, "Recupera el cuerpo de un amigo", "Porque ser un héroe incluye ser también sepulturero espacial", "es", 20),
				new DefaultMissionData(MissionType.ObtainHoneycomb, "Consigue una colmena", "Porque incluso en el espacio, todos necesitamos un poco de miel y risas", "es", 80),
				new DefaultMissionData(MissionType.SurviveCrewmates, "Preserva la Vida del Grupo", "¡Asegúrate de que al menos {0} tripulantes sobrevivan a la odisea espacial!", "es", 100),
				new DefaultMissionData(MissionType.KillMonster, "Elimina al Monstruo", "Embarcate en una misión audaz para eliminar a una amenazante criatura", "es", 50),
				new DefaultMissionData(MissionType.ObtainGenerator, "Obteniendo el Aparato", "Obtén el Generador de la Fábrica", "es", 50)
			};
		}
	}
	public class DefaultMissionData
	{
		public MissionType MissionType { get; }

		public string MissionName { get; }

		public string MissionObjective { get; }

		public int MissionReward { get; }

		public string LanguageCode { get; }

		public DefaultMissionData(MissionType missionType, string missionName, string missionObjective, string languageCode, int missionReward)
		{
			MissionType = missionType;
			MissionName = missionName;
			MissionObjective = missionObjective;
			LanguageCode = languageCode;
			MissionReward = missionReward;
		}
	}
	public static class StringUtilities
	{
		public static string NoMissionsMessageEnglish { get; private set; }

		public static string NoMissionsMessageSpanish { get; private set; }

		public static string CompletedMissionMessageEnglish { get; private set; }

		public static string CompletedMissionMessageSpanish { get; private set; }

		public static string NoCompletedMissionsMessageEnglish { get; private set; }

		public static string NoCompletedMissionsMessageSpanish { get; private set; }

		public static string CompletedMissionsCountMessageEnglish { get; private set; }

		public static string CompletedMissionsCountMessageSpanish { get; private set; }

		public static string NameEnglish { get; private set; }

		public static string NameSpanish { get; private set; }

		public static string ObjectiveEnglish { get; private set; }

		public static string ObjectiveSpanish { get; private set; }

		public static string StatusEnglish { get; private set; }

		public static string StatusSpanish { get; private set; }

		public static string RewardEnglish { get; private set; }

		public static string RewardSpanish { get; private set; }

		public static string NewMissionsAvailableEnglish { get; private set; }

		public static string NewMissionsAvailableSpanish { get; private set; }

		public static string GetName(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? NameEnglish : ((!(languageCode == "es")) ? NameEnglish : NameSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetObjective(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? ObjectiveEnglish : ((!(languageCode == "es")) ? ObjectiveEnglish : ObjectiveSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetStatus(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? StatusEnglish : ((!(languageCode == "es")) ? StatusEnglish : StatusSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetReward(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? RewardEnglish : ((!(languageCode == "es")) ? RewardEnglish : RewardSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		static StringUtilities()
		{
			NoCompletedMissionsMessageEnglish = "No completed missions";
			NoCompletedMissionsMessageSpanish = "No hay misiones completadas";
			CompletedMissionsCountMessageEnglish = "You have completed {0}\nmissions.\n\nHere are your rewards:\n\n";
			CompletedMissionsCountMessageSpanish = "Has completado {0}\nmisiones.\n\nAqui estan tus \nrecompensas:\n\n";
			NameEnglish = "Name: ";
			NameSpanish = "Nombre: ";
			ObjectiveEnglish = "Objective: ";
			ObjectiveSpanish = "Objetivo: ";
			StatusEnglish = "Status: ";
			StatusSpanish = "Estado: ";
			RewardEnglish = "Reward: ";
			RewardSpanish = "Recompensa: ";
			NewMissionsAvailableEnglish = "New missions are available!";
			NewMissionsAvailableSpanish = "Hay nuevas misiones disponibles!";
			NoMissionsMessageEnglish = "There are no missions at the moment, the mission system only works within the range of the factories, sorry :']\n\n";
			NoMissionsMessageSpanish = "No hay misiones en este momento, el sistema de misiones solo funciona dentro del rango de las fábricas, lo siento :']\n\n";
			CompletedMissionMessageEnglish = "Misiones Completadas:\n";
			CompletedMissionMessageSpanish = "Misiones Completadas:\n";
		}

		public static string GetNoMissionsMessage(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? NoMissionsMessageEnglish : ((!(languageCode == "es")) ? NoMissionsMessageEnglish : NoMissionsMessageSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetCompletedMissionsCountMessage(string languageCode, int count)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? string.Format(CompletedMissionsCountMessageEnglish, count) : ((!(languageCode == "es")) ? string.Format(CompletedMissionsCountMessageEnglish, count) : string.Format(CompletedMissionsCountMessageSpanish, count)));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetCompletedMissionMessage(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? CompletedMissionMessageEnglish : ((!(languageCode == "es")) ? CompletedMissionMessageEnglish : CompletedMissionMessageSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetNoCompletedMissionsMessage(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? NoCompletedMissionsMessageEnglish : ((!(languageCode == "es")) ? NoCompletedMissionsMessageEnglish : NoCompletedMissionsMessageSpanish));
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetNewMissionsAvailableMessage(string languageCode)
		{
			if (1 == 0)
			{
			}
			string result = ((languageCode == "en") ? NewMissionsAvailableEnglish : ((!(languageCode == "es")) ? NewMissionsAvailableEnglish : NewMissionsAvailableSpanish));
			if (1 == 0)
			{
			}
			return result;
		}
	}
}

BepInEx/plugins/LethalCompanyInputUtils/LethalCompanyInputUtils.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalCompanyInputUtils.Data;
using LethalCompanyInputUtils.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("LethalCompanyInputUtils")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9e95a88c49ab86635dbebf33cfb26802052a8769")]
[assembly: AssemblyProduct("LethalCompanyInputUtils")]
[assembly: AssemblyTitle("LethalCompanyInputUtils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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 LethalCompanyInputUtils
{
	public static class LcInputActionApi
	{
		private static readonly Dictionary<string, LcInputActions> InputActionsMap = new Dictionary<string, LcInputActions>();

		private static IReadOnlyCollection<LcInputActions> InputActions => InputActionsMap.Values;

		internal static void LoadIntoUI(KepRemapPanel panel)
		{
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00d9: 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)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			UpdateFontScaling(panel);
			AdjustSizeAndPos(panel);
			LayoutElement val = EnsureLayoutElement(panel);
			val.minHeight = 0f;
			List<RemappableKey> remappableKeys = panel.remappableKeys;
			int num = remappableKeys.Count((RemappableKey key) => !key.gamepadOnly);
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Loaded)
				{
					continue;
				}
				foreach (InputActionReference actionRef in inputAction.ActionRefs)
				{
					InputBinding val2 = ((IEnumerable<InputBinding>)(object)actionRef.action.bindings).First();
					string name = ((InputBinding)(ref val2)).name;
					RemappableKey item = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						gamepadOnly = false
					};
					remappableKeys.Insert(num++, item);
					RemappableKey item2 = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						rebindingIndex = 1,
						gamepadOnly = true
					};
					remappableKeys.Add(item2);
				}
				inputAction.Loaded = true;
			}
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
			val.minHeight += (panel.maxVertical + 1f) * panel.verticalOffset;
		}

		private static void UpdateFontScaling(KepRemapPanel panel)
		{
			TextMeshProUGUI component = ((Component)panel.keyRemapSlotPrefab.transform.Find("Text (1)")).GetComponent<TextMeshProUGUI>();
			if (!((TMP_Text)component).enableAutoSizing)
			{
				((TMP_Text)component).fontSizeMax = ((TMP_Text)component).fontSize;
				((TMP_Text)component).fontSizeMin = ((TMP_Text)component).fontSize - 4f;
				((TMP_Text)component).enableAutoSizing = true;
			}
		}

		private static void AdjustSizeAndPos(KepRemapPanel panel)
		{
			GameObject gameObject = ((Component)((Transform)panel.keyRemapContainer).parent).gameObject;
			if (gameObject.GetComponent<ContentSizeFitter>() == null)
			{
				panel.keyRemapContainer.SetPivotY(1f);
				panel.keyRemapContainer.SetAnchorMinY(1f);
				panel.keyRemapContainer.SetAnchorMaxY(1f);
				panel.keyRemapContainer.SetAnchoredPosY(0f);
				panel.keyRemapContainer.SetLocalPosY(0f);
				ContentSizeFitter obj = gameObject.AddComponent<ContentSizeFitter>();
				obj.horizontalFit = (FitMode)0;
				obj.verticalFit = (FitMode)1;
			}
		}

		private static LayoutElement EnsureLayoutElement(KepRemapPanel panel)
		{
			GameObject gameObject = ((Component)((Transform)panel.keyRemapContainer).parent).gameObject;
			LayoutElement component = gameObject.GetComponent<LayoutElement>();
			if (component != null)
			{
				return component;
			}
			return gameObject.AddComponent<LayoutElement>();
		}

		internal static void CalculateVerticalMaxForGamepad(KepRemapPanel panel)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			int num = panel.remappableKeys.Count((RemappableKey key) => key.gamepadOnly);
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
			LayoutElement obj = EnsureLayoutElement(panel);
			obj.minHeight += (panel.maxVertical + 3f) * panel.verticalOffset;
		}

		internal static void ResetLoadedInputActions()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Loaded = false;
			}
		}

		internal static void RegisterInputActions(LcInputActions lcInputActions, InputActionMapBuilder builder)
		{
			if (!InputActionsMap.TryAdd(lcInputActions.Id, lcInputActions))
			{
				Logging.Logger.LogWarning((object)("The mod [" + lcInputActions.Plugin.GUID + "] instantiated an Actions class [" + lcInputActions.GetType().Name + "] more than once!\n\t These classes should be treated as singletons!, do not instantiate more than once!"));
			}
			else
			{
				lcInputActions.CreateInputActions(in builder);
				InputActionSetupExtensions.AddActionMap(lcInputActions.GetAsset(), builder.Build());
				lcInputActions.GetAsset().Enable();
				lcInputActions.OnAssetLoaded();
				lcInputActions.Load();
				lcInputActions.BuildActionRefs();
			}
		}

		internal static void DisableForRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Enabled)
				{
					inputAction.Disable();
				}
			}
		}

		internal static void ReEnableFromRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.WasEnabled)
				{
					inputAction.Enable();
				}
			}
		}

		internal static void SaveOverrides()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Save();
			}
		}
	}
	[BepInPlugin("com.rune580.LethalCompanyInputUtils", "Lethal Company Input Utils", "0.4.4")]
	public class LethalCompanyInputUtilsPlugin : BaseUnityPlugin
	{
		public const string ModId = "com.rune580.LethalCompanyInputUtils";

		public const string ModName = "Lethal Company Input Utils";

		public const string ModVersion = "0.4.4";

		private Harmony? _harmony;

		private void Awake()
		{
			Logging.SetLogSource(((BaseUnityPlugin)this).Logger);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.rune580.LethalCompanyInputUtils");
			SceneManager.activeSceneChanged += OnSceneChanged;
			FsUtils.EnsureControlsDir();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.rune580.LethalCompanyInputUtils is loaded!");
		}

		private static void OnSceneChanged(Scene current, Scene next)
		{
			LcInputActionApi.ResetLoadedInputActions();
		}
	}
}
namespace LethalCompanyInputUtils.Utils
{
	internal static class AssemblyUtils
	{
		public static BepInPlugin? GetBepInPlugin(this Assembly assembly)
		{
			foreach (Type validType in assembly.GetValidTypes())
			{
				BepInPlugin customAttribute = ((MemberInfo)validType).GetCustomAttribute<BepInPlugin>();
				if (customAttribute != null)
				{
					return customAttribute;
				}
			}
			return null;
		}

		public static IEnumerable<Type> GetValidTypes(this Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type type) => (object)type != null);
			}
		}
	}
	internal static class FsUtils
	{
		public static string SaveDir { get; } = GetSaveDir();


		public static string Pre041ControlsDir { get; } = Path.Combine(Paths.BepInExRootPath, "controls");


		public static string ControlsDir { get; } = Path.Combine(Paths.ConfigPath, "controls");


		private static string GetSaveDir()
		{
			string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
			return Path.Combine(folderPath, "AppData", "LocalLow", "ZeekerssRBLX", "Lethal Company");
		}

		public static void EnsureControlsDir()
		{
			if (!Directory.Exists(ControlsDir))
			{
				Directory.CreateDirectory(ControlsDir);
			}
		}
	}
	internal static class Logging
	{
		private static ManualLogSource? _logSource;

		internal static ManualLogSource Logger { get; } = _logSource;


		internal static void SetLogSource(ManualLogSource logSource)
		{
			_logSource = logSource;
		}
	}
	internal static class RuntimeHelper
	{
		public static void SetLocalPosY(this RectTransform rectTransform, float y)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = ((Transform)rectTransform).localPosition;
			((Transform)rectTransform).localPosition = new Vector3(localPosition.x, y, localPosition.z);
		}

		public static void SetPivotY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.pivot = new Vector2(rectTransform.pivot.x, y);
		}

		public static void SetAnchorMinY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchorMin = new Vector2(rectTransform.anchorMin.x, y);
		}

		public static void SetAnchorMaxY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchorMax = new Vector2(rectTransform.anchorMax.x, y);
		}

		public static void SetAnchoredPosY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, y);
		}
	}
}
namespace LethalCompanyInputUtils.Patches
{
	public static class InputControlPathPatches
	{
		[HarmonyPatch]
		public static class ToHumanReadableStringPatch
		{
			public static IEnumerable<MethodBase> TargetMethods()
			{
				return from method in AccessTools.GetDeclaredMethods(typeof(InputControlPath))
					where method.Name == "ToHumanReadableString" && method.ReturnType == typeof(string)
					select method;
			}

			public static void Postfix(ref string __result)
			{
				string text = __result;
				if ((text == "<InputUtils-Gamepad-Not-Bound>" || text == "<InputUtils-Kbm-Not-Bound>") ? true : false)
				{
					__result = "";
				}
			}
		}
	}
	public static class KeyRemapPanelPatches
	{
		[HarmonyPatch(typeof(KepRemapPanel), "LoadKeybindsUI")]
		public static class LoadKeybindsUIPatch
		{
			public static void Prefix(KepRemapPanel __instance)
			{
				LcInputActionApi.DisableForRebind();
				LcInputActionApi.LoadIntoUI(__instance);
			}

			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Expected O, but got Unknown
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Expected O, but got Unknown
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Expected O, but got Unknown
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Expected O, but got Unknown
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				FieldInfo maxVerticalField = AccessTools.Field(typeof(KepRemapPanel), "maxVertical");
				val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsLdarg(code, (int?)0)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.LoadsField(code, maxVerticalField, false)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 2f), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Add), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Conv_I4), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null)), (string)null)
				});
				val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LcInputActionApi), "CalculateVerticalMaxForGamepad", new Type[1] { typeof(KepRemapPanel) }, (Type[])null))
				});
				return val.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(KepRemapPanel), "UnloadKeybindsUI")]
		public static class UnloadKeybindsUIPatch
		{
			public static void Prefix()
			{
				LcInputActionApi.SaveOverrides();
				LcInputActionApi.ReEnableFromRebind();
			}
		}
	}
}
namespace LethalCompanyInputUtils.Data
{
	[Serializable]
	public struct BindingOverride
	{
		public string? action;

		public string? origPath;

		public string? path;
	}
	[Serializable]
	public class BindingOverrides
	{
		public List<BindingOverride> overrides;

		private BindingOverrides()
		{
			overrides = new List<BindingOverride>();
		}

		public BindingOverrides(IEnumerable<InputBinding> bindings)
		{
			//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)
			overrides = new List<BindingOverride>();
			foreach (InputBinding binding in bindings)
			{
				InputBinding current = binding;
				if (((InputBinding)(ref current)).hasOverrides)
				{
					BindingOverride item = new BindingOverride
					{
						action = ((InputBinding)(ref current)).action,
						origPath = ((InputBinding)(ref current)).path,
						path = ((InputBinding)(ref current)).overridePath
					};
					overrides.Add(item);
				}
			}
		}

		public void LoadInto(InputActionAsset asset)
		{
			foreach (BindingOverride @override in overrides)
			{
				InputAction obj = asset.FindAction(@override.action, false);
				if (obj != null)
				{
					InputActionRebindingExtensions.ApplyBindingOverride(obj, @override.path, (string)null, @override.origPath);
				}
			}
		}

		public static BindingOverrides FromJson(string json)
		{
			BindingOverrides bindingOverrides = new BindingOverrides();
			JToken value = JsonConvert.DeserializeObject<JObject>(json).GetValue("overrides");
			bindingOverrides.overrides = value.ToObject<List<BindingOverride>>();
			return bindingOverrides;
		}
	}
}
namespace LethalCompanyInputUtils.Api
{
	[AttributeUsage(AttributeTargets.Property)]
	public class InputActionAttribute : Attribute
	{
		public readonly string KbmPath;

		public string? ActionId { get; set; }

		public string? GamepadPath { get; set; }

		public InputActionType ActionType { get; set; } = (InputActionType)1;


		public string? KbmInteractions { get; set; }

		public string? GamepadInteractions { get; set; }

		public string? Name { get; set; }

		[Obsolete("Prefer using the named optional params instead.")]
		public InputActionAttribute(string action, string kbmPath, string gamepadPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ActionId = action;
			KbmPath = kbmPath;
			GamepadPath = gamepadPath;
		}

		public InputActionAttribute(string kbmPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			KbmPath = kbmPath;
		}
	}
	public class InputActionBindingBuilder
	{
		private readonly InputActionMapBuilder _mapBuilder;

		private string? _actionId;

		private string? _kbmPath;

		private string? _gamepadPath;

		private string? _kbmInteractions;

		private string? _gamepadInteractions;

		private InputActionType _actionType;

		private string? _name;

		internal InputActionBindingBuilder(InputActionMapBuilder mapBuilder)
		{
			_mapBuilder = mapBuilder;
		}

		public InputActionBindingBuilder WithActionId(string actionId)
		{
			_actionId = actionId;
			return this;
		}

		public InputActionBindingBuilder WithKbmPath(string kbmPath)
		{
			_kbmPath = kbmPath;
			return this;
		}

		public InputActionBindingBuilder WithGamepadPath(string gamepadPath)
		{
			_gamepadPath = gamepadPath;
			return this;
		}

		public InputActionBindingBuilder WithKbmInteractions(string? kbmInteractions)
		{
			_kbmInteractions = kbmInteractions;
			return this;
		}

		public InputActionBindingBuilder WithGamepadInteractions(string? gamepadInteractions)
		{
			_gamepadInteractions = gamepadInteractions;
			return this;
		}

		public InputActionBindingBuilder WithActionType(InputActionType actionType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_actionType = actionType;
			return this;
		}

		public InputActionBindingBuilder WithBindingName(string? name)
		{
			_name = name;
			return this;
		}

		public InputAction Finish()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (_name == null)
			{
				_name = _actionId;
			}
			InputAction val = new InputAction(_actionId, _actionType, (string)null, (string)null, (string)null, (string)null);
			_mapBuilder.WithAction(val);
			if (_kbmPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_kbmPath, _actionId, (string)null, (string)null, _kbmInteractions, _name));
			}
			if (_gamepadPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_gamepadPath, _actionId, (string)null, (string)null, _gamepadInteractions, _name));
			}
			return val;
		}
	}
	public class InputActionMapBuilder
	{
		private readonly InputActionMap _actionMap = new InputActionMap(mapName);

		public InputActionMapBuilder(string mapName)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown


		public InputActionMapBuilder WithAction(InputAction action)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddAction(_actionMap, action.name, action.type, (string)null, (string)null, (string)null, (string)null, (string)null);
			return this;
		}

		public InputActionMapBuilder WithBinding(InputBinding binding)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddBinding(_actionMap, binding);
			return this;
		}

		public InputActionBindingBuilder NewActionBinding()
		{
			return new InputActionBindingBuilder(this);
		}

		internal InputActionMap Build()
		{
			return _actionMap;
		}
	}
	public abstract class LcInputActions
	{
		public const string UnboundKeyboardAndMouseIdentifier = "<InputUtils-Kbm-Not-Bound>";

		public const string UnboundGamepadIdentifier = "<InputUtils-Gamepad-Not-Bound>";

		private readonly string _jsonPath;

		private readonly List<InputActionReference> _actionRefs = new List<InputActionReference>();

		internal bool Loaded;

		private readonly Dictionary<PropertyInfo, InputActionAttribute> _inputProps;

		public InputActionAsset Asset { get; }

		internal bool WasEnabled { get; private set; }

		public bool Enabled => Asset.enabled;

		internal IReadOnlyCollection<InputActionReference> ActionRefs => _actionRefs;

		internal string Id => Plugin.GUID + "." + MapName;

		public BepInPlugin Plugin { get; }

		protected virtual string MapName => GetType().Name;

		internal InputActionAsset GetAsset()
		{
			return Asset;
		}

		protected LcInputActions()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			Asset = ScriptableObject.CreateInstance<InputActionAsset>();
			Plugin = Assembly.GetCallingAssembly().GetBepInPlugin() ?? throw new InvalidOperationException();
			_jsonPath = Path.Combine(FsUtils.ControlsDir, Id + ".json");
			InputActionMapBuilder inputActionMapBuilder = new InputActionMapBuilder(Id);
			PropertyInfo[] properties = GetType().GetProperties();
			_inputProps = new Dictionary<PropertyInfo, InputActionAttribute>();
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				InputActionAttribute customAttribute = propertyInfo.GetCustomAttribute<InputActionAttribute>();
				if (customAttribute != null && !(propertyInfo.PropertyType != typeof(InputAction)))
				{
					InputActionAttribute inputActionAttribute = customAttribute;
					if (inputActionAttribute.ActionId == null)
					{
						string text = (inputActionAttribute.ActionId = propertyInfo.Name);
					}
					inputActionAttribute = customAttribute;
					if (inputActionAttribute.GamepadPath == null)
					{
						string text = (inputActionAttribute.GamepadPath = "<InputUtils-Gamepad-Not-Bound>");
					}
					string kbmPath = (string.IsNullOrEmpty(customAttribute.KbmPath) ? "<InputUtils-Kbm-Not-Bound>" : customAttribute.KbmPath);
					inputActionMapBuilder.NewActionBinding().WithActionId(customAttribute.ActionId).WithActionType(customAttribute.ActionType)
						.WithBindingName(customAttribute.Name)
						.WithKbmPath(kbmPath)
						.WithGamepadPath(customAttribute.GamepadPath)
						.WithKbmInteractions(customAttribute.KbmInteractions)
						.WithGamepadInteractions(customAttribute.GamepadInteractions)
						.Finish();
					_inputProps[propertyInfo] = customAttribute;
				}
			}
			LcInputActionApi.RegisterInputActions(this, inputActionMapBuilder);
		}

		public virtual void CreateInputActions(in InputActionMapBuilder builder)
		{
		}

		public virtual void OnAssetLoaded()
		{
		}

		internal void BuildActionRefs()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<PropertyInfo, InputActionAttribute> inputProp in _inputProps)
			{
				inputProp.Deconstruct(out var key, out var value);
				PropertyInfo propertyInfo = key;
				InputActionAttribute inputActionAttribute = value;
				InputAction value2 = Asset.FindAction(inputActionAttribute.ActionId, false);
				propertyInfo.SetValue(this, value2);
			}
			IEnumerable<InputActionReference> collection = ((IEnumerable<InputActionMap>)(object)Asset.actionMaps).SelectMany((InputActionMap map) => (IEnumerable<InputAction>)(object)map.actions).Select((Func<InputAction, InputActionReference>)InputActionReference.Create);
			_actionRefs.AddRange(collection);
		}

		public void Enable()
		{
			WasEnabled = Asset.enabled;
			Asset.Enable();
		}

		public void Disable()
		{
			WasEnabled = Asset.enabled;
			Asset.Disable();
		}

		internal void Save()
		{
			BindingOverrides bindingOverrides = new BindingOverrides(Asset.bindings);
			File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides));
		}

		internal void Load()
		{
			try
			{
				ApplyMigrations();
			}
			catch (Exception ex)
			{
				Logging.Logger.LogError((object)"Got error when applying migrations, skipping...");
				Logging.Logger.LogError((object)ex);
			}
			if (!File.Exists(_jsonPath))
			{
				return;
			}
			try
			{
				BindingOverrides.FromJson(File.ReadAllText(_jsonPath)).LoadInto(Asset);
			}
			catch (Exception ex2)
			{
				Logging.Logger.LogError((object)ex2);
			}
		}

		private void ApplyMigrations()
		{
			string text = Path.Combine(FsUtils.Pre041ControlsDir, Id + ".json");
			if (File.Exists(text) && !File.Exists(_jsonPath))
			{
				File.Move(text, _jsonPath);
			}
			if (!File.Exists(_jsonPath) || !File.ReadAllText(_jsonPath).Replace(" ", "").Contains("\"origPath\":\"\""))
			{
				return;
			}
			BindingOverrides bindingOverrides = BindingOverrides.FromJson(File.ReadAllText(_jsonPath));
			for (int i = 0; i < bindingOverrides.overrides.Count; i++)
			{
				BindingOverride value = bindingOverrides.overrides[i];
				if (string.IsNullOrEmpty(value.origPath) && value.path != null)
				{
					if (value.path.StartsWith("<Keyboard>") || value.path.StartsWith("<Mouse>"))
					{
						value.origPath = "<InputUtils-Kbm-Not-Bound>";
					}
					else
					{
						value.origPath = "<InputUtils-Gamepad-Not-Bound>";
					}
					bindingOverrides.overrides[i] = value;
				}
			}
			File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides));
		}
	}
}

BepInEx/plugins/NoSellLimit.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("NoSellLimit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("NoSellLimit")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NoSellLimit")]
[assembly: AssemblyTitle("NoSellLimit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace NoSellLimit
{
	[BepInPlugin("viviko.NoSellLimit", "NoSellLimit", "1.0.0")]
	public class NoSellLimit : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(DepositItemsDesk))]
		[HarmonyPatch("PlaceItemOnCounter")]
		public static class PlaceItemOnCounterPatch
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(DepositItemsDesk), "deskObjectsContainer");
				bool flag = false;
				int num = -1;
				int num2 = -1;
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (!flag && val.opcode == OpCodes.Ldfld && (FieldInfo)val.operand == fieldInfo)
					{
						flag = true;
						num = i - 1;
					}
					else if (flag && val.opcode == OpCodes.Bge)
					{
						num2 = i;
						break;
					}
				}
				if (num > -1 && num2 > -1)
				{
					list[num].opcode = OpCodes.Nop;
					list.RemoveRange(num, num2 - num + 1);
				}
				return list.AsEnumerable();
			}
		}

		private const string modGUID = "viviko.NoSellLimit";

		private const string modName = "NoSellLimit";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("viviko.NoSellLimit");

		private static NoSellLimit Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("viviko.NoSellLimit");
			harmony.PatchAll();
			mls.LogInfo((object)"Plugin NoSellLimit is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "NoSellLimit";

		public const string PLUGIN_NAME = "NoSellLimit";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/plugins/TwoHandedStorage.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("TwoHandedStorage")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("TwoHandedStorage")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TwoHandedStorage")]
[assembly: AssemblyTitle("TwoHandedStorage")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace TwoHandedStorage
{
	[BepInPlugin("viviko.TwoHandedStorage", "TwoHandedStorage", "1.0.0")]
	public class TwoHandedStorage : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerControllerB))]
		internal class PlayerControllerBPatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")]
			private static void SetHoverTipAndCurrentInteractTriggerPatch(ref InteractTrigger ___hoveringOverTrigger)
			{
				if (Object.op_Implicit((Object)(object)___hoveringOverTrigger))
				{
					___hoveringOverTrigger.twoHandedItemAllowed = true;
				}
			}
		}

		private const string modGUID = "viviko.TwoHandedStorage";

		private const string modName = "TwoHandedStorage";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("viviko.TwoHandedStorage");

		private static TwoHandedStorage Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("viviko.TwoHandedStorage");
			harmony.PatchAll();
			mls.LogInfo((object)"Plugin TwoHandedStorage is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TwoHandedStorage";

		public const string PLUGIN_NAME = "TwoHandedStorage";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/plugins/LateCompanyV1.0.9.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("LateCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+45a32594ae7b3615a3d1703738f777272caa8e30")]
[assembly: AssemblyProduct("LateCompany")]
[assembly: AssemblyTitle("LateCompany")]
[assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LateCompany
{
	public static class PluginInfo
	{
		public const string GUID = "twig.latecompany";

		public const string PrintName = "Late Company";

		public const string Version = "1.0.9";
	}
	[BepInPlugin("twig.latecompany", "Late Company", "1.0.9")]
	internal class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> configLateJoinOrbitOnly;

		public static bool AllowJoiningWhileLanded = false;

		public static bool LobbyJoinable = true;

		public void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			configLateJoinOrbitOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allow joining while landed", false, "Allow players to join while the ship is landed. (Will probably break some things)");
			AllowJoiningWhileLanded = configLateJoinOrbitOnly.Value;
			Harmony val = new Harmony("twig.latecompany");
			val.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.Log((LogLevel)16, (object)"Late Company loaded!");
		}

		public static void SetLobbyJoinable(bool joinable)
		{
			LobbyJoinable = joinable;
			GameNetworkManager.Instance.SetLobbyJoinable(joinable);
			QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>();
			if (Object.op_Implicit((Object)(object)val))
			{
				val.inviteFriendsTextAlpha.alpha = (joinable ? 1f : 0.2f);
			}
		}
	}
}
namespace LateCompany.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")]
	[HarmonyWrapSafe]
	internal static class LeaveLobbyAtGameStart_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
	[HarmonyWrapSafe]
	internal static class ConnectionApproval_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(ConnectionApprovalRequest request, ConnectionApprovalResponse response)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (request.ClientNetworkId != NetworkManager.Singleton.LocalClientId && response.Reason.Contains("Game has already started") && Plugin.LobbyJoinable)
			{
				response.Reason = "";
				response.CreatePlayerObject = false;
				response.Approved = true;
				response.Pending = false;
			}
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "DisableInviteFriendsButton")]
	internal static class DisableInviteFriendsButton_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")]
	internal static class InviteFriendsButton_Patch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			if (Plugin.LobbyJoinable)
			{
				GameNetworkManager.Instance.InviteFriendsUI();
			}
			return false;
		}
	}
	internal class RpcEnum : NetworkBehaviour
	{
		public static int None => 0;

		public static int Client => 2;

		public static int Server => 1;
	}
	internal static class WeatherSync
	{
		public static bool DoOverride = false;

		public static LevelWeatherType CurrentWeather = (LevelWeatherType)(-1);
	}
	[HarmonyPatch(typeof(RoundManager), "__rpc_handler_1193916134")]
	[HarmonyWrapSafe]
	internal static class __rpc_handler_1193916134_Patch
	{
		public static FieldInfo RPCExecStage = typeof(NetworkBehaviour).GetField("__rpc_exec_stage", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPrefix]
		private static bool Prefix(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002e: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if ((Object)(object)networkManager != (Object)null && networkManager.IsListening && !networkManager.IsHost)
			{
				try
				{
					int num = default(int);
					ByteUnpacker.ReadValueBitPacked(reader, ref num);
					int num2 = default(int);
					ByteUnpacker.ReadValueBitPacked(reader, ref num2);
					if (((FastBufferReader)(ref reader)).Position < ((FastBufferReader)(ref reader)).Length)
					{
						int num3 = default(int);
						ByteUnpacker.ReadValueBitPacked(reader, ref num3);
						num3 -= 255;
						if (num3 < 0)
						{
							throw new Exception("In case of emergency, break glass.");
						}
						WeatherSync.CurrentWeather = (LevelWeatherType)num3;
						WeatherSync.DoOverride = true;
					}
					RPCExecStage.SetValue(target, RpcEnum.Client);
					((RoundManager)((target is RoundManager) ? target : null)).GenerateNewLevelClientRpc(num, num2);
					RPCExecStage.SetValue(target, RpcEnum.None);
					return false;
				}
				catch
				{
					WeatherSync.DoOverride = false;
					((FastBufferReader)(ref reader)).Seek(0);
					return true;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SetToCurrentLevelWeather")]
	internal static class SetToCurrentLevelWeather_Patch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (WeatherSync.DoOverride)
			{
				RoundManager.Instance.currentLevel.currentWeather = WeatherSync.CurrentWeather;
				WeatherSync.DoOverride = false;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")]
	[HarmonyWrapSafe]
	internal static class OnPlayerConnectedClientRpc_Patch
	{
		public static MethodInfo BeginSendClientRpc = typeof(RoundManager).GetMethod("__beginSendClientRpc", BindingFlags.Instance | BindingFlags.NonPublic);

		public static MethodInfo EndSendClientRpc = typeof(RoundManager).GetMethod("__endSendClientRpc", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPostfix]
		private static void Postfix(ulong clientId, int connectedPlayers, ulong[] connectedPlayerIdsOrdered, int assignedPlayerObjectId, int serverMoneyAmount, int levelID, int profitQuota, int timeUntilDeadline, int quotaFulfilled, int randomSeed)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected I4, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			PlayerControllerB val = instance.allPlayerScripts[assignedPlayerObjectId];
			if (instance.connectedPlayersAmount + 1 >= instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: false);
			}
			val.DisablePlayerModel(instance.allPlayerObjects[assignedPlayerObjectId], true, true);
			if (((NetworkBehaviour)instance).IsServer && !instance.inShipPhase)
			{
				RoundManager instance2 = RoundManager.Instance;
				ClientRpcParams val2 = default(ClientRpcParams);
				val2.Send = new ClientRpcSendParams
				{
					TargetClientIds = new List<ulong> { clientId }
				};
				ClientRpcParams val3 = val2;
				FastBufferWriter val4 = (FastBufferWriter)BeginSendClientRpc.Invoke(instance2, new object[3] { 1193916134u, val3, 0 });
				BytePacker.WriteValueBitPacked(val4, StartOfRound.Instance.randomMapSeed);
				BytePacker.WriteValueBitPacked(val4, StartOfRound.Instance.currentLevelID);
				BytePacker.WriteValueBitPacked(val4, instance2.currentLevel.currentWeather + 255);
				EndSendClientRpc.Invoke(instance2, new object[4] { val4, 1193916134u, val3, 0 });
				FastBufferWriter val5 = (FastBufferWriter)BeginSendClientRpc.Invoke(instance2, new object[3] { 2729232387u, val3, 0 });
				EndSendClientRpc.Invoke(instance2, new object[4] { val5, 2729232387u, val3, 0 });
			}
			instance.livingPlayers = instance.connectedPlayersAmount + 1;
			for (int i = 0; i < instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val6 = instance.allPlayerScripts[i];
				if (val6.isPlayerControlled && val6.isPlayerDead)
				{
					instance.livingPlayers--;
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
	[HarmonyWrapSafe]
	internal static class OnPlayerDC_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (StartOfRound.Instance.inShipPhase || (Plugin.AllowJoiningWhileLanded && StartOfRound.Instance.shipHasLanded))
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")]
	internal static class SetShipReadyToLand_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (StartOfRound.Instance.connectedPlayersAmount + 1 < StartOfRound.Instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "StartGame")]
	internal static class StartGame_Patch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			Plugin.SetLobbyJoinable(joinable: false);
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
	internal static class OnShipLandedMiscEvents_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (Plugin.AllowJoiningWhileLanded && StartOfRound.Instance.connectedPlayersAmount + 1 < StartOfRound.Instance.allPlayerScripts.Length)
			{
				Plugin.SetLobbyJoinable(joinable: true);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
	internal static class ShipLeave_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Plugin.SetLobbyJoinable(joinable: false);
		}
	}
}

BepInEx/plugins/ScoopysVarietyMod/ScoopysVarietyMod.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen.Graph;
using HarmonyLib;
using LethalLib.Extras;
using LethalLib.Modules;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LethalExtension")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalExtension")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("94d2de4e-bed1-40e3-b759-cf53352d4930")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace ScoopysVarietyMod
{
	[BepInPlugin("ScoopysVarietyMod", "Scoopy's Variety Mod", "0.4")]
	public class plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Object))]
		private class ItemGroupPatch
		{
			[HarmonyPatch("Equals")]
			[HarmonyPrefix]
			public static bool FixItemGroupEquals(ref bool __result, object __instance, object other)
			{
				ItemGroup val = (ItemGroup)((__instance is ItemGroup) ? __instance : null);
				if (val != null)
				{
					ItemGroup val2 = (ItemGroup)((other is ItemGroup) ? other : null);
					if (val2 != null)
					{
						__result = val.itemSpawnTypeName == val2.itemSpawnTypeName;
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("GenerateNewFloor")]
			[HarmonyPostfix]
			private static void FixTeleportDoors()
			{
				Instance.MLS.LogInfo((object)"Attempting to fix entrance teleporters.");
				SpawnSyncedObject[] array = Object.FindObjectsOfType<SpawnSyncedObject>();
				NetworkManager val = Object.FindObjectOfType<NetworkManager>();
				bool flag = false;
				bool flag2 = false;
				int num = 0;
				SpawnSyncedObject[] array2 = array;
				foreach (SpawnSyncedObject val2 in array2)
				{
					if (((Object)val2.spawnPrefab).name == "EntranceTeleportA_LE")
					{
						NetworkPrefab val3 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "EntranceTeleportA");
						if (val3 == null)
						{
							Instance.MLS.LogError((object)"Failed to find EntranceTeleportA prefab.");
							return;
						}
						Instance.MLS.LogInfo((object)"Found EntranceTeleportA prefab.");
						flag = true;
						val2.spawnPrefab = val3.Prefab;
						Instance.MLS.LogInfo((object)"Replaced EntranceTeleportA prefab.");
					}
					else if (((Object)val2.spawnPrefab).name == "EntranceTeleportB_LE")
					{
						NetworkPrefab val4 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "EntranceTeleportB");
						if (val4 == null)
						{
							Instance.MLS.LogError((object)"Failed to find EntranceTeleportB prefab.");
							return;
						}
						Instance.MLS.LogInfo((object)"Found EntranceTeleportB prefab.");
						flag2 = true;
						val2.spawnPrefab = val4.Prefab;
						Instance.MLS.LogInfo((object)"Replaced EntranceTeleportB prefab.");
					}
					else if (((Object)val2.spawnPrefab).name == "VentPlaceholder")
					{
						NetworkPrefab val5 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "VentEntrance");
						if (val5 == null)
						{
							Instance.MLS.LogError((object)"Failed to find VentEntrance prefab.");
							return;
						}
						Instance.MLS.LogInfo((object)"Found and replaced VentEntrance prefab.");
						num++;
						val2.spawnPrefab = val5.Prefab;
					}
				}
				if (!flag && !flag2)
				{
					Instance.MLS.LogError((object)"Failed to find entrance teleporters to replace.");
				}
				if (num == 0)
				{
					Instance.MLS.LogError((object)"No vents found to replace.");
				}
				else
				{
					Instance.MLS.LogInfo((object)$"{num} vents were successfully replacd.");
				}
			}
		}

		private const string modGUID = "ScoopysVarietyMod";

		private const string modName = "Scoopy's Variety Mod";

		private const string modVersion = "0.4";

		private static plugin Instance;

		private readonly Harmony harmony = new Harmony("ScoopysVarietyMod");

		private ConfigEntry<int> configCastleRarity;

		private ConfigEntry<string> configCastleMoons;

		private ConfigEntry<bool> configGuaranteeCastle;

		private ConfigEntry<int> configGuitarRarity;

		private ConfigEntry<int> configFireaxeRarity;

		private string[] MoonConfigs = new string[11]
		{
			"all", "paid", "unpaid", "titan", "rend", "dine", "vow", "experimentation", "assurance", "offense",
			"march"
		};

		internal ManualLogSource MLS;

		public static AssetBundle Assets;

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			MLS = Logger.CreateLogSource("ScoopysVarietyMod");
			string? directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			configCastleRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Castle Interior", "CastleDungeonSpawnChance", 300, new ConfigDescription("Adjusts likelihood of the castle dungeon spawning. Higher values increases the chance of spawning. At the max value of 300, the spawn chance would be approx 50% on vanilla moons", (AcceptableValueBase)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			configCastleMoons = ((BaseUnityPlugin)this).Config.Bind<string>("Castle Interior", "CastleDungeonMoons", "all", new ConfigDescription("The moon(s) that the castle dungeon can spawn on. Invalid valueas will prevent spawning", (AcceptableValueBase)new AcceptableValueList<string>(MoonConfigs), Array.Empty<object>()));
			configGuaranteeCastle = ((BaseUnityPlugin)this).Config.Bind<bool>("Castle Interior", "CastleDungeonGuaranteed", false, new ConfigDescription("If enabled, the castle dungeon will be effectively guaranteed to spawn on moons where it can spawn as per CastleDungeonMoons.", (AcceptableValueBase)null, Array.Empty<object>()));
			configGuitarRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Scrap", "GuitarRarity", 10, new ConfigDescription("Frequency of Guitar scrap spawning. Higher values are more common. Set to 0 to disable spawns.", (AcceptableValueBase)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			configFireaxeRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Scrap", "FireaxeRarity", 5, new ConfigDescription("Frequency of Fire Axe scrap spawning. Higher values are more common. Set to 0 to disable spawns.", (AcceptableValueBase)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			Assets = AssetBundle.LoadFromFile(Path.Combine(directoryName, "ScoopysVarietyMod"));
			if ((Object)(object)Assets == (Object)null)
			{
				MLS.LogError((object)"Failed to unpack ScoopysVarietyMod assetbundle.");
			}
			Item val = Assets.LoadAsset<Item>("Assets/ScoopysVarietyMod/ScrapAssets/Guitar/WeezerGuitar.asset");
			Item val2 = Assets.LoadAsset<Item>("Assets/ScoopysVarietyMod/ScrapAssets/FireAxe/FireAxe.asset");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				MLS.LogError((object)"Failed to load all items");
			}
			else
			{
				NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
				NetworkPrefabs.RegisterNetworkPrefab(val2.spawnPrefab);
				Items.RegisterScrap(val, configGuitarRarity.Value, (LevelTypes)(-1));
				Items.RegisterScrap(val2, configFireaxeRarity.Value, (LevelTypes)896);
				MLS.LogInfo((object)"Custom Scrap Loaded Successfully");
			}
			GameObject val3 = Assets.LoadAsset<GameObject>("Assets/ScoopysVarietyMod/CastleAssets/Prefabs/RoundWoodDoor.prefab");
			GameObject val4 = Assets.LoadAsset<GameObject>("Assets/ScoopysVarietyMod/CastleAssets/Prefabs/CellDoorFull.prefab");
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				MLS.LogError((object)"Failed to load a door asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val3);
			NetworkPrefabs.RegisterNetworkPrefab(val4);
			MLS.LogInfo((object)"Unpacking Castle Dungeon Assets...");
			DungeonFlow val5 = Assets.LoadAsset<DungeonFlow>("Assets/ScoopysVarietyMod/CastleAssets/CastleFlow.asset");
			if ((Object)(object)val5 == (Object)null)
			{
				MLS.LogError((object)"Failed to load Castle Dungeon Flow.");
				return;
			}
			MLS.LogInfo((object)"Loading dungeon defs...");
			DungeonDef obj = ScriptableObject.CreateInstance<DungeonDef>();
			obj.dungeonFlow = val5;
			obj.rarity = (configGuaranteeCastle.Value ? 99999 : configCastleRarity.Value);
			MLS.LogInfo((object)"Registering dungeon flows");
			Dungeon.AddDungeon(obj, LevelsFromConfig(configCastleMoons.Value.ToLower()));
			harmony.PatchAll(typeof(plugin));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(ItemGroupPatch));
			MLS.LogInfo((object)"Initialised Successfully");
		}

		private LevelTypes LevelsFromConfig(string configValue)
		{
			switch (configValue)
			{
			case "all":
				return (LevelTypes)956;
			case "paid":
				return (LevelTypes)896;
			case "unpaid":
				return (LevelTypes)60;
			case "titan":
				return (LevelTypes)512;
			case "offense":
				return (LevelTypes)32;
			case "vow":
				return (LevelTypes)16;
			case "assurance":
				return (LevelTypes)8;
			case "experimentation":
				return (LevelTypes)4;
			case "dine":
				return (LevelTypes)256;
			case "rend":
				return (LevelTypes)128;
			case "march":
				return (LevelTypes)64;
			default:
				MLS.LogError((object)"Invalid config value for dungeon moon spawning. Config value must match the preset values");
				return (LevelTypes)1;
			}
		}
	}
}

BepInEx/plugins/SCPCBDunGen/SCPCBDunGen.dll

Decompiled 8 months ago
using System;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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("SCPCBDunGen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+92cc7d2daf8e7425b3688b3db64919dae1c21b4e")]
[assembly: AssemblyProduct("SCPCBDunGen")]
[assembly: AssemblyTitle("SCPCBDunGen")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class SCPDoorMover : NetworkBehaviour
{
	public AnimatedObjectTrigger animObjectTrigger;

	public NavMeshObstacle navObstacle;

	private float fEnemyDoorMeter;

	private void ToggleDoor(PlayerControllerB player)
	{
		animObjectTrigger.TriggerAnimation(player);
		((Behaviour)navObstacle).enabled = !animObjectTrigger.boolValue;
	}

	private void OnTriggerStay(Collider other)
	{
		if ((Object)(object)animObjectTrigger == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !((NetworkBehaviour)this).IsServer || animObjectTrigger.boolValue || !((Component)other).CompareTag("Enemy"))
		{
			return;
		}
		EnemyAICollisionDetect component = ((Component)other).GetComponent<EnemyAICollisionDetect>();
		if ((Object)(object)component != (Object)null)
		{
			fEnemyDoorMeter += Time.deltaTime * component.mainScript.openDoorSpeedMultiplier;
			if (fEnemyDoorMeter > 1f)
			{
				fEnemyDoorMeter = 0f;
				animObjectTrigger.TriggerAnimationNonPlayer(component.mainScript.useSecondaryAudiosOnAnimatedObjects, true, false);
				((Behaviour)navObstacle).enabled = !animObjectTrigger.boolValue;
			}
		}
	}
}
namespace SCPCBDunGen
{
	[BepInPlugin("SCPCBDunGen", "SCPCBDunGen", "1.3.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SCPCBDunGen : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("GenerateNewFloor")]
			[HarmonyPostfix]
			private static void FixTeleportDoors(ref RuntimeDungeon ___dungeonGenerator)
			{
				if (((Object)___dungeonGenerator.Generator.DungeonFlow).name != "SCPFlow")
				{
					return;
				}
				Instance.mls.LogInfo((object)"Attempting to fix entrance teleporters.");
				SpawnSyncedObject[] array = Object.FindObjectsOfType<SpawnSyncedObject>();
				NetworkManager val = Object.FindObjectOfType<NetworkManager>();
				NetworkPrefab val2 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "VentEntrance");
				if (val2 == null)
				{
					Instance.mls.LogError((object)"Failed to find VentEntrance prefab.");
					return;
				}
				bool flag = false;
				bool flag2 = false;
				int num = 0;
				SpawnSyncedObject[] array2 = array;
				foreach (SpawnSyncedObject val3 in array2)
				{
					if (((Object)val3.spawnPrefab).name == "EntranceTeleportA_EMPTY")
					{
						NetworkPrefab val4 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "EntranceTeleportA");
						if (val4 == null)
						{
							Instance.mls.LogError((object)"Failed to find EntranceTeleportA prefab.");
							return;
						}
						Instance.mls.LogInfo((object)"Found and replaced EntranceTeleportA prefab.");
						flag = true;
						val3.spawnPrefab = val4.Prefab;
					}
					else if (((Object)val3.spawnPrefab).name == "EntranceTeleportB_EMPTY")
					{
						NetworkPrefab val5 = val.NetworkConfig.Prefabs.m_Prefabs.First((NetworkPrefab x) => ((Object)x.Prefab).name == "EntranceTeleportB");
						if (val5 == null)
						{
							Instance.mls.LogError((object)"Failed to find EntranceTeleportB prefab.");
							return;
						}
						Instance.mls.LogInfo((object)"Found and replaced EntranceTeleportB prefab.");
						flag2 = true;
						val3.spawnPrefab = val5.Prefab;
					}
					else if (((Object)val3.spawnPrefab).name == "VentDummy")
					{
						Instance.mls.LogInfo((object)"Found and replaced VentEntrance prefab.");
						num++;
						val3.spawnPrefab = val2.Prefab;
					}
				}
				if (!flag)
				{
					Instance.mls.LogError((object)"Failed to find entrance teleporter for main entrance to replace.");
				}
				if (!flag2)
				{
					Instance.mls.LogError((object)"Failed to find entrance teleporter for fire exit to replace.");
				}
				if (num == 0)
				{
					Instance.mls.LogError((object)"No vents found to replace.");
				}
				else
				{
					Instance.mls.LogInfo((object)$"{num} vents found and replaced with network prefab.");
				}
			}

			[HarmonyPatch("SpawnScrapInLevel")]
			[HarmonyPrefix]
			private static bool SetItemSpawnPoints(ref SelectableLevel ___currentLevel, ref RuntimeDungeon ___dungeonGenerator)
			{
				if (((Object)___dungeonGenerator.Generator.DungeonFlow).name != "SCPFlow")
				{
					return true;
				}
				SpawnableItemWithRarity val = ___currentLevel.spawnableScrap.Find((SpawnableItemWithRarity x) => x.spawnableItem.itemName == "Bottles");
				if (val == null)
				{
					Instance.mls.LogError((object)"Failed to find bottle bin item for reference snatching; is this a custom moon without the bottle bin item?");
					return true;
				}
				SpawnableItemWithRarity val2 = ___currentLevel.spawnableScrap.Find((SpawnableItemWithRarity x) => x.spawnableItem.itemName == "Golden cup");
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				ItemGroup spawnableItems = val.spawnableItem.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "GeneralItemClass");
				ItemGroup val3 = val.spawnableItem.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "TabletopItems");
				ItemGroup spawnableItems2 = (ItemGroup)((val2 == null) ? ((object)val3) : ((object)val2.spawnableItem.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "SmallItems")));
				RandomScrapSpawn[] array = Object.FindObjectsOfType<RandomScrapSpawn>();
				foreach (RandomScrapSpawn val4 in array)
				{
					switch (((Object)val4.spawnableItems).name)
					{
					case "GeneralItemClassDUMMY":
						val4.spawnableItems = spawnableItems;
						num++;
						break;
					case "TabletopItemsDUMMY":
						val4.spawnableItems = val3;
						num2++;
						break;
					case "SmallItemsDUMMY":
						val4.spawnableItems = spawnableItems2;
						num3++;
						break;
					}
				}
				Instance.mls.LogInfo((object)$"Totals for scrap replacement: General: {num}, Tabletop: {num2}, Small: {num3}");
				if (num + num2 + num3 < 10)
				{
					Instance.mls.LogWarning((object)"Unusually low scrap spawn count; scrap may be sparse.");
				}
				return true;
			}
		}

		private const string modGUID = "SCPCBDunGen";

		private const string modName = "SCPCBDunGen";

		private const string modVersion = "1.3.2";

		private readonly Harmony harmony = new Harmony("SCPCBDunGen");

		private static SCPCBDunGen Instance;

		internal ManualLogSource mls;

		public static AssetBundle SCPCBAssets;

		private ConfigEntry<int> configSCPRarity;

		private ConfigEntry<string> configMoonsOld;

		private ConfigEntry<string> configMoons;

		private ConfigEntry<bool> configGuaranteedSCP;

		private void Awake()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("SCPCBDunGen");
			SCPCBAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "scpcb_dungeon"));
			if ((Object)(object)SCPCBAssets == (Object)null)
			{
				mls.LogError((object)"Failed to load SCPCB Dungeon assets.");
				return;
			}
			GameObject val = SCPCBAssets.LoadAsset<GameObject>("assets/Mods/SCP/prefabs/SCPDoorBtn.prefab");
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)"Failed to load SCP Door.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val);
			harmony.PatchAll(typeof(SCPCBDunGen));
			harmony.PatchAll(typeof(RoundManagerPatch));
			configSCPRarity = ((BaseUnityPlugin)this).Config.Bind<int>("General", "FoundationRarity", 100, new ConfigDescription("How rare it is for the foundation to be chosen. Higher values increases the chance of spawning the foundation.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			configMoonsOld = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FoundationMoons", "NULL", new ConfigDescription("OLD CONFIG SETTING, HAS NO EFFECT. Only here to clear the legacy config from updating.", (AcceptableValueBase)null, Array.Empty<object>()));
			configMoons = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FoundationMoonsList", "TitanLevel", new ConfigDescription("The moon(s) that the foundation can spawn on, in the form of a comma separated list of selectable level names (e.g. \"TitanLevel,RendLevel,DineLevel\")\nNOTE: These must be the internal data names of the levels (all vanilla moons are \"MoonnameLevel\", for modded moon support you will have to find their name if it doesn't follow the convention).\nUse \"all\" to generate in all moons (including modded and unsupported moons). May cause problems if fire exit count on a moon is > 1.", (AcceptableValueBase)null, Array.Empty<object>()));
			configGuaranteedSCP = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FoundationGuaranteed", false, new ConfigDescription("If enabled, the foundation will be effectively guaranteed to spawn. Only recommended for debugging/sightseeing purposes.", (AcceptableValueBase)null, Array.Empty<object>()));
			if (configMoonsOld.Value != "NULL")
			{
				mls.LogWarning((object)"Old config parameters detected; config has changed since 1.3.1, check the config and set FoundationMoons to NULL to suppress this warning (and change FoundationMoonsList if you want)");
			}
			DungeonFlow val2 = SCPCBAssets.LoadAsset<DungeonFlow>("assets/Mods/SCP/data/SCPFlow.asset");
			if ((Object)(object)val2 == (Object)null)
			{
				mls.LogError((object)"Failed to load SCP:CB Dungeon Flow.");
				return;
			}
			DungeonDef val3 = ScriptableObject.CreateInstance<DungeonDef>();
			val3.dungeonFlow = val2;
			val3.rarity = (configGuaranteedSCP.Value ? 99999 : configSCPRarity.Value);
			val3.firstTimeDungeonAudio = SCPCBAssets.LoadAsset<AudioClip>("assets/Mods/SCP/snd/Horror8.ogg");
			if (configMoons.Value == "all")
			{
				Dungeon.AddDungeon(val3, (LevelTypes)(-1));
				mls.LogInfo((object)"Registered SCP dungeon for all moons. Compatability not guaranteed!");
			}
			else
			{
				string[] array = configMoons.Value.Split(',', StringSplitOptions.RemoveEmptyEntries);
				Dungeon.AddDungeon(val3, (LevelTypes)1, array);
				mls.LogInfo((object)("Registered SCP dungeon for the following moons: " + configMoons.Value));
			}
			mls.LogInfo((object)"SCP:CB DunGen for Lethal Company [Version 1.3.2] successfully loaded.");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "SCPCBDunGen";

		public const string PLUGIN_NAME = "SCPCBDunGen";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/SnapRotateDecor.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using SnapRotateFurniture.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SnapRotateDecor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SnapRotateDecor")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f8855d2f-421c-493b-a4b8-096a44d3d8ee")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SnapRotateFurniture
{
	[BepInPlugin("SleeplessKyru.SnapRotateFurniture", "Snap Rotate Furniture", "1.0.1")]
	public class SleeplessModBase : BaseUnityPlugin
	{
		private const string modGUID = "SleeplessKyru.SnapRotateFurniture";

		private const string modName = "Snap Rotate Furniture";

		private const string modVersion = "1.0.1";

		private readonly Harmony harmony = new Harmony("SleeplessKyru.SnapRotateFurniture");

		private static SleeplessModBase Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("SleeplessKyru.SnapRotateFurniture");
			mls.LogInfo((object)"Snap Rotate Furniture by Sleepless Kyru has loaded!");
			harmony.PatchAll(typeof(SleeplessModBase));
			harmony.PatchAll(typeof(SnapRotateFurniturePatch));
		}
	}
}
namespace SnapRotateFurniture.Patches
{
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal class SnapRotateFurniturePatch
	{
		private static bool wasButtonPressed;

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void rotateFurniturePatch(ref PlayerActions ___playerActions, ref Transform ___ghostObject)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (!IngamePlayerSettings.Instance.playerInput.actions.FindAction("ActivateItem", false).IsPressed())
			{
				if (StartOfRound.Instance.localPlayerUsingController)
				{
					MovementActions movement = ___playerActions.Movement;
					if (((MovementActions)(ref movement)).ActivateItem.IsPressed())
					{
						goto IL_004c;
					}
				}
				if (wasButtonPressed)
				{
					wasButtonPressed = false;
					float num = 45f;
					Vector3 eulerAngles = ___ghostObject.eulerAngles;
					float num2 = Mathf.Round(eulerAngles.y / num) * num + num;
					___ghostObject.eulerAngles = new Vector3(eulerAngles.x, num2, eulerAngles.z);
				}
				return;
			}
			goto IL_004c;
			IL_004c:
			wasButtonPressed = true;
		}
	}
}

BepInEx/plugins/GroanTubeScrap.dll

Decompiled 8 months ago
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LaserTweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LaserTweaks")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4963e0ea-7a99-4390-9cae-a4bdd01b6b43")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace GroanTubeScrap
{
	public class Assets
	{
		public static AssetBundle MainAssetBundle;

		public static Item Item;

		internal static Stream GetEmbededResource(string name)
		{
			return Assembly.GetExecutingAssembly().GetManifestResourceStream("GroanTubeScrap." + name);
		}

		public static void Init()
		{
			MainAssetBundle = AssetBundle.LoadFromStream(GetEmbededResource("groantube.bundle"));
			Item = MainAssetBundle.LoadAsset<Item>("Assets/Mods/GroanTubeScrap/GroanTube.asset");
		}
	}
	internal class GroanTubeItem : NoisemakerProp
	{
		private bool localState;

		[Header("Horrible Color Sync")]
		[Tooltip("Seekers made me do this. Look at implementation of (Item.materialVariants)")]
		public Material[] altMaterials;

		public int altSelect = -1;

		public override int GetItemDataToSave()
		{
			return altSelect;
		}

		public override void LoadItemSaveData(int saveData)
		{
			altSelect = Mathf.Clamp(saveData, 0, altMaterials.Length - 1);
			Material sharedMaterial = altMaterials[altSelect];
			((Renderer)((GrabbableObject)this).mainObjectRenderer).sharedMaterial = sharedMaterial;
		}

		public override void Start()
		{
			((NoisemakerProp)this).Start();
			if (((NetworkBehaviour)this).IsOwner && altMaterials.Length != 0)
			{
				if (altSelect < 0)
				{
					altSelect = Random.Range(0, altMaterials.Length);
				}
				((GrabbableObject)this).SyncBatteryServerRpc(altSelect);
			}
		}

		public override void ChargeBatteries()
		{
			if (!(((GrabbableObject)this).insertedBattery.charge < 0f))
			{
				int num = Mathf.RoundToInt(((GrabbableObject)this).insertedBattery.charge * 100f);
				num = Mathf.Clamp(num, 0, altMaterials.Length - 1);
				((GrabbableObject)this).LoadItemSaveData(num);
				((GrabbableObject)this).insertedBattery.charge = -1f;
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				if (((NetworkBehaviour)this).IsOwner)
				{
					buttonDown = !localState;
					((GrabbableObject)this).isSendingItemRPC = ((GrabbableObject)this).isSendingItemRPC + 1;
					((GrabbableObject)this).ActivateItemServerRpc(false, buttonDown);
				}
				OnItemUseLocal(buttonDown);
			}
		}

		private void OnItemUseLocal(bool state)
		{
			localState = state;
			base.triggerAnimator.SetTrigger("Spin");
			PlayAudio((!state) ? 1 : 0);
		}

		private void PlayAudio(int index)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			AudioClip val = base.noiseSFX[index];
			float num = (float)base.noisemakerRandom.Next((int)(base.minLoudness * 100f), (int)(base.maxLoudness * 100f)) / 100f;
			float pitch = (float)base.noisemakerRandom.Next((int)(base.minPitch * 100f), (int)(base.maxPitch * 100f)) / 100f;
			base.noiseAudio.pitch = pitch;
			base.noiseAudio.PlayOneShot(val, num);
			WalkieTalkie.TransmitOneShotAudio(base.noiseAudio, val, num);
			RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, base.noiseRange, num, 0, ((GrabbableObject)this).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0);
			if (base.minLoudness >= 0.6f && (Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
			{
				((GrabbableObject)this).playerHeldBy.timeSinceMakingLoudNoise = 0f;
			}
		}
	}
	[BepInPlugin("Kittenji.GroanTubeScrap", "Groan Tube Scrap", "1.0.0")]
	public class Loader : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GameNetworkManager))]
		internal class GameNetworkManagerPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch()
			{
				((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().AddNetworkPrefab(Assets.Item.spawnPrefab);
			}
		}

		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartOfRoundPatch
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void AwakePatch(ref StartOfRound __instance)
			{
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Expected O, but got Unknown
				SelectableLevel[] levels = __instance.levels;
				foreach (SelectableLevel val in levels)
				{
					if (val.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)Assets.Item))
					{
						continue;
					}
					int num = SpawnRateOverride.Value;
					if (num < 1)
					{
						SpawnableItemWithRarity val2 = val.spawnableScrap.Find((SpawnableItemWithRarity s) => Object.op_Implicit((Object)(object)s.spawnableItem) && Object.op_Implicit((Object)(object)s.spawnableItem.spawnPrefab) && ((Object)s.spawnableItem.spawnPrefab).name == "RobotToy");
						if (val2 != null)
						{
							num = val2.rarity;
						}
						else if (val.spawnableScrap.Count > 0)
						{
							int num2 = int.MaxValue;
							foreach (SpawnableItemWithRarity item2 in val.spawnableScrap)
							{
								if (item2.rarity < num2)
								{
									num2 = item2.rarity;
								}
							}
							num = num2;
						}
					}
					num = Mathf.Clamp(num, 1, 100);
					SpawnableItemWithRarity item = new SpawnableItemWithRarity
					{
						spawnableItem = Assets.Item,
						rarity = num
					};
					val.spawnableScrap.Add(item);
				}
				if (!__instance.allItemsList.itemsList.Contains(Assets.Item))
				{
					__instance.allItemsList.itemsList.Add(Assets.Item);
				}
			}
		}

		private const string modGUID = "Kittenji.GroanTubeScrap";

		private readonly Harmony harmony = new Harmony("Kittenji.GroanTubeScrap");

		private static ConfigEntry<int> SpawnRateOverride;

		private const string ItemReferenceName = "RobotToy";

		private void Awake()
		{
			Assets.Init();
			SpawnRateOverride = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Spawn Rate Override", -1, "Override the spawn rate for this item, this affects all moons. By default, it uses the spawn rate of the Toy Cube item so it spawns in coordination with other toys.");
			harmony.PatchAll();
		}
	}
}

BepInEx/plugins/ImmersiveVisor.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ImmersiveVisor")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Immersive Visor for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ImmersiveVisor")]
[assembly: AssemblyTitle("ImmersiveVisor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ImmersiveVisor
{
	[BepInPlugin("ImmersiveVisor", "ImmersiveVisor", "1.0.0")]
	public class ImmersiveVisor : BaseUnityPlugin
	{
		public enum VisorState
		{
			Clean,
			LightCrack,
			HardCrack,
			Count
		}

		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartOfRoundPatch
		{
			[HarmonyPatch("ReviveDeadPlayers")]
			[HarmonyPostfix]
			private static void ReviveDeadPlayersPatch()
			{
				SetVisorState(VisorState.Clean);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		internal class PlayerControllerBPatch
		{
			[HarmonyPatch("ConnectClientToPlayerObject")]
			[HarmonyPostfix]
			private static void ConnectClientToPlayerObject(ref Transform ___localVisor, ref Camera ___visorCamera)
			{
				if ((Object)(object)Instance.visor == (Object)null)
				{
					if ((Object)(object)___localVisor != (Object)null)
					{
						((Object)___localVisor).name = "destroy_soon";
						Object.Destroy((Object)(object)((Component)___localVisor).gameObject);
					}
					Transform transform = GameObject.Find("Systems/Rendering").transform;
					Instance.visor = Object.Instantiate<GameObject>(visorPrefab, transform);
					((Object)Instance.visor).name = "ImmersiveHUDHelmetModel";
					Instance.visorMesh = ((Component)Instance.visor.transform.GetChild(0)).GetComponent<MeshRenderer>();
				}
				___localVisor = Instance.visor.transform;
			}

			[HarmonyPatch("DamagePlayer")]
			[HarmonyPostfix]
			private static void DamagePlayerPatch(ref int ___health, ref bool ___criticallyInjured, ref bool ___isPlayerDead, ref CauseOfDeath causeOfDeath)
			{
				//IL_0021: 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_0024: Invalid comparison between Unknown and I4
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Invalid comparison between Unknown and I4
				if (visorState == VisorState.HardCrack)
				{
					return;
				}
				if (___isPlayerDead)
				{
					SetVisorState(VisorState.HardCrack);
					return;
				}
				CauseOfDeath val = causeOfDeath;
				if (((int)val != 5 && val - 9 > 2) || 1 == 0)
				{
					if (___health <= 35)
					{
						SetVisorState(VisorState.HardCrack);
					}
					else if (___health <= 70)
					{
						SetVisorState(VisorState.LightCrack);
					}
				}
			}
		}

		private static VisorState visorState = VisorState.Clean;

		private readonly Harmony harmony = new Harmony("ImmersiveVisor");

		public static ImmersiveVisor Instance;

		public static AssetBundle MainAsset;

		private static GameObject visorPrefab;

		private static Material[] _matVisorArray;

		private static AudioClip[] _visorDamageSFX;

		private static float _visorSFXVolume = 3f;

		private GameObject visor;

		private MeshRenderer visorMesh;

		internal static ManualLogSource ImmersiveVisorLog;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			ImmersiveVisorLog = new ManualLogSource("ImmersiveVisorLogSource");
			Logger.Sources.Add((ILogSource)(object)ImmersiveVisorLog);
			ImmersiveVisorLog.LogInfo((object)"Immersive Visor Mod Loaded");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			if ((Object)(object)MainAsset == (Object)null)
			{
				MainAsset = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "immersivevisor"));
			}
			visorPrefab = MainAsset.LoadAsset<GameObject>("Assets/ImmersiveVisor/ImmersiveVisorHelmet.prefab");
			if ((Object)(object)visorPrefab == (Object)null)
			{
				ImmersiveVisorLog.LogError((object)"Failed to load immersive visor prefab from asset bundle");
			}
			_matVisorArray = (Material[])(object)new Material[3];
			_matVisorArray[0] = MainAsset.LoadAsset<Material>("Assets/ImmersiveVisor/Materials/HelmetVisor_0.mat");
			_matVisorArray[1] = MainAsset.LoadAsset<Material>("Assets/ImmersiveVisor/Materials/HelmetVisor_1.mat");
			_matVisorArray[2] = MainAsset.LoadAsset<Material>("Assets/ImmersiveVisor/Materials/HelmetVisor_2.mat");
			_visorDamageSFX = (AudioClip[])(object)new AudioClip[2];
			_visorDamageSFX[0] = MainAsset.LoadAsset<AudioClip>("Assets/ImmersiveVisor/Audio/sfx_visor_crack_light.wav");
			_visorDamageSFX[1] = MainAsset.LoadAsset<AudioClip>("Assets/ImmersiveVisor/Audio/sfx_visor_crack_hard.wav");
			harmony.PatchAll();
		}

		private static void SetVisorState(VisorState state)
		{
			if (state != VisorState.Count)
			{
				visorState = state;
				Material[] materials = ((Renderer)Instance.visorMesh).materials;
				materials[2] = _matVisorArray[(int)state];
				((Renderer)Instance.visorMesh).materials = materials;
				if (visorState != 0)
				{
					HUDManager.Instance.UIAudio.PlayOneShot(_visorDamageSFX[(int)(visorState - 1)], _visorSFXVolume);
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ImmersiveVisor";

		public const string PLUGIN_NAME = "ImmersiveVisor";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

MonoBleedingEdge/BepInEx/plugins/LC_API.dll

Decompiled 8 months ago
using System;
using System.Collections.Concurrent;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LC_API.BundleAPI;
using LC_API.Comp;
using LC_API.Data;
using LC_API.Extensions;
using LC_API.GameInterfaceAPI;
using LC_API.ManualPatches;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("LC_API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Utilities for plugin devs")]
[assembly: AssemblyFileVersion("2.1.1.0")]
[assembly: AssemblyInformationalVersion("2.1.1")]
[assembly: AssemblyProduct("LC_API")]
[assembly: AssemblyTitle("LC_API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LC_API
{
	internal static class CheatDatabase
	{
		private const string DAT_CD_BROADCAST = "LC_API_CD_Broadcast";

		private const string SIG_REQ_GUID = "LC_API_ReqGUID";

		private const string SIG_SEND_MODS = "LC_APISendMods";

		private static Dictionary<string, PluginInfo> PluginsLoaded = new Dictionary<string, PluginInfo>();

		public static void RunLocalCheatDetector()
		{
			PluginsLoaded = Chainloader.PluginInfos;
			using Dictionary<string, PluginInfo>.ValueCollection.Enumerator enumerator = PluginsLoaded.Values.GetEnumerator();
			while (enumerator.MoveNext())
			{
				switch (enumerator.Current.Metadata.GUID)
				{
				case "mikes.lethalcompany.mikestweaks":
				case "mom.llama.enhancer":
				case "Posiedon.GameMaster":
				case "LethalCompanyScalingMaster":
				case "verity.amberalert":
					ModdedServer.SetServerModdedOnly();
					break;
				}
			}
		}

		public static void OtherPlayerCheatDetector()
		{
			Plugin.Log.LogWarning((object)"Asking all other players for their mod list..");
			GameTips.ShowTip("Mod List:", "Asking all other players for installed mods..");
			GameTips.ShowTip("Mod List:", "Check the logs for more detailed results.\n<size=13>(Note that if someone doesnt show up on the list, they may not have LC_API installed)</size>");
			Networking.Broadcast("LC_API_CD_Broadcast", "LC_API_ReqGUID");
		}

		internal static void CDNetGetString(string data, string signature)
		{
			if (data == "LC_API_CD_Broadcast" && signature == "LC_API_ReqGUID")
			{
				string text = "";
				foreach (PluginInfo value in PluginsLoaded.Values)
				{
					text = text + "\n" + value.Metadata.GUID;
				}
				Networking.Broadcast(GameNetworkManager.Instance.localPlayerController.playerUsername + " responded with these mods:" + text, "LC_APISendMods");
			}
			if (signature == "LC_APISendMods")
			{
				GameTips.ShowTip("Mod List:", data);
				Plugin.Log.LogWarning((object)data);
			}
		}
	}
	[BepInPlugin("LC_API", "LC_API", "2.1.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private ConfigEntry<bool> configOverrideModServer;

		private ConfigEntry<bool> configLegacyAssetLoading;

		private ConfigEntry<bool> configDisableBundleLoader;

		public static bool Initialized { get; private set; }

		private void Awake()
		{
			//IL_00a5: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			configOverrideModServer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force modded server browser", false, "Should the API force you into the modded server browser?");
			configLegacyAssetLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Legacy asset bundle loading", false, "Should the BundleLoader use legacy asset loading? Turning this on may help with loading assets from older plugins.");
			configDisableBundleLoader = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Disable BundleLoader", false, "Should the BundleLoader be turned off? Enable this if you are having problems with mods that load assets using a different method from LC_API's BundleLoader.");
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogWarning((object)"\n.____    _________           _____  __________ .___  \r\n|    |   \\_   ___ \\         /  _  \\ \\______   \\|   | \r\n|    |   /    \\  \\/        /  /_\\  \\ |     ___/|   | \r\n|    |___\\     \\____      /    |    \\|    |    |   | \r\n|_______ \\\\______  /______\\____|__  /|____|    |___| \r\n        \\/       \\//_____/        \\/                 \r\n                                                     ");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Starting up..");
			if (configOverrideModServer.Value)
			{
				ModdedServer.SetServerModdedOnly();
			}
			Harmony val = new Harmony("ModAPI");
			MethodInfo methodInfo = AccessTools.Method(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated", (Type[])null, (Type[])null);
			AccessTools.Method(typeof(GameNetworkManager), "LobbyDataIsJoinable", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ServerPatch), "OnLobbyCreate", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(MenuManager), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(ServerPatch), "CacheMenuManager", (Type[])null, (Type[])null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(ServerPatch), "ChatInterpreter", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, new Action<string, string>(CheatDatabase.CDNetGetString));
			Networking.GetListString = (Action<List<string>, string>)Delegate.Combine(Networking.GetListString, new Action<List<string>, string>(Networking.LCAPI_NET_SYNCVAR_SET));
		}

		internal void Start()
		{
			Initialize();
		}

		internal void OnDestroy()
		{
			Initialize();
		}

		internal void Initialize()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!Initialized)
			{
				Initialized = true;
				if (!configDisableBundleLoader.Value)
				{
					BundleLoader.Load(configLegacyAssetLoading.Value);
				}
				GameObject val = new GameObject("API");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<LC_APIManager>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Started!");
				CheatDatabase.RunLocalCheatDetector();
			}
		}

		internal static void PatchMethodManual(MethodInfo method, MethodInfo patch, Harmony harmony)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			harmony.Patch((MethodBase)method, new HarmonyMethod(patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LC_API";

		public const string PLUGIN_NAME = "LC_API";

		public const string PLUGIN_VERSION = "2.1.1";
	}
}
namespace LC_API.ServerAPI
{
	public static class ModdedServer
	{
		private static bool moddedOnly;

		[Obsolete("Use SetServerModdedOnly() instead. This will be removed/private in a future update.")]
		public static bool setModdedOnly;

		public static bool ModdedOnly => moddedOnly;

		public static void SetServerModdedOnly()
		{
			moddedOnly = true;
			Plugin.Log.LogMessage((object)"A plugin has set your game to only allow you to play with other people who have mods!");
		}

		public static void OnSceneLoaded()
		{
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && ModdedOnly)
			{
				GameNetworkManager instance = GameNetworkManager.Instance;
				instance.gameVersionNum += 16440;
				setModdedOnly = true;
			}
		}
	}
	public static class Networking
	{
		public static Action<string, string> GetString = delegate
		{
		};

		public static Action<List<string>, string> GetListString = delegate
		{
		};

		public static Action<int, string> GetInt = delegate
		{
		};

		public static Action<float, string> GetFloat = delegate
		{
		};

		public static Action<Vector3, string> GetVector3 = delegate
		{
		};

		private static Dictionary<string, string> syncStringVars = new Dictionary<string, string>();

		public static void Broadcast(string data, string signature)
		{
			if (data.Contains("/"))
			{
				Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
				return;
			}
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDstring.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(List<string> data, string signature)
		{
			string text = "";
			foreach (string datum in data)
			{
				if (datum.Contains("/"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
					return;
				}
				if (datum.Contains("\n"))
				{
					Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( NewLine )");
					return;
				}
				text = text + datum + "\n";
			}
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data?.ToString() + "/" + signature + "/" + NetworkBroadcastDataType.BDlistString.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(int data, string signature)
		{
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDint.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(float data, string signature)
		{
			HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDfloat.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
		}

		public static void Broadcast(Vector3 data, string signature)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			HUDManager instance = HUDManager.Instance;
			string[] obj = new string[9] { "<size=0>NWE/", null, null, null, null, null, null, null, null };
			Vector3 val = data;
			obj[1] = ((object)(Vector3)(ref val)).ToString();
			obj[2] = "/";
			obj[3] = signature;
			obj[4] = "/";
			obj[5] = NetworkBroadcastDataType.BDvector3.ToString();
			obj[6] = "/";
			obj[7] = GameNetworkManager.Instance.localPlayerController.playerClientId.ToString();
			obj[8] = "/</size>";
			instance.AddTextToChatOnServer(string.Concat(obj), -1);
		}

		public static void RegisterSyncVariable(string name)
		{
			if (!syncStringVars.ContainsKey(name))
			{
				syncStringVars.Add(name, "");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot register Sync Variable! A Sync Variable has already been registered with name " + name));
			}
		}

		public static void SetSyncVariable(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
				Broadcast(new List<string> { name, value }, "LCAPI_NET_SYNCVAR_SET");
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		private static void SetSyncVariableB(string name, string value)
		{
			if (syncStringVars.ContainsKey(name))
			{
				syncStringVars[name] = value;
			}
			else
			{
				Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
			}
		}

		internal static void LCAPI_NET_SYNCVAR_SET(List<string> list, string arg2)
		{
			if (arg2 == "LCAPI_NET_SYNCVAR_SET")
			{
				SetSyncVariableB(list[0], list[1]);
			}
		}

		public static string GetSyncVariable(string name)
		{
			if (syncStringVars.ContainsKey(name))
			{
				return syncStringVars[name];
			}
			Plugin.Log.LogError((object)("Cannot get the value of Sync Variable " + name + " as it is not registered!"));
			return "";
		}

		private static void GotString(string data, string signature)
		{
		}

		private static void GotInt(int data, string signature)
		{
		}

		private static void GotFloat(float data, string signature)
		{
		}

		private static void GotVector3(Vector3 data, string signature)
		{
		}
	}
}
namespace LC_API.ManualPatches
{
	internal static class ServerPatch
	{
		internal static bool OnLobbyCreate(GameNetworkManager __instance, Result result, Lobby lobby)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if ((int)result != 1)
			{
				Debug.LogError((object)$"Lobby could not be created! {result}", (Object)(object)__instance);
			}
			__instance.lobbyHostSettings.lobbyName = "[MODDED]" + __instance.lobbyHostSettings.lobbyName.ToString();
			Plugin.Log.LogMessage((object)"server pre-setup success");
			return true;
		}

		internal static bool CacheMenuManager(MenuManager __instance)
		{
			LC_APIManager.MenuManager = __instance;
			return true;
		}

		internal static bool ChatInterpreter(HUDManager __instance, string chatMessage)
		{
			//IL_0312: 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_03a2: 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)
			if (!chatMessage.Contains("NWE") || !chatMessage.Contains("<size=0>"))
			{
				return true;
			}
			string[] array = chatMessage.Split(new char[1] { '/' });
			if (array.Length < 5)
			{
				if (array.Length >= 3)
				{
					if (!int.TryParse(array[4], out var result))
					{
						Plugin.Log.LogWarning((object)"Failed to parse player ID!!");
						return false;
					}
					if ((result == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
					{
						return false;
					}
					Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result2);
					switch (result2)
					{
					case NetworkBroadcastDataType.BDstring:
						Networking.GetString(array[1], array[2]);
						break;
					case NetworkBroadcastDataType.BDint:
						Networking.GetInt(int.Parse(array[1]), array[2]);
						break;
					case NetworkBroadcastDataType.BDfloat:
						Networking.GetFloat(float.Parse(array[1]), array[2]);
						break;
					case NetworkBroadcastDataType.BDvector3:
					{
						string[] array2 = array[1].Replace("(", "").Replace(")", "").Split(new char[1] { ',' });
						Vector3 arg = default(Vector3);
						if (array2.Length == 3)
						{
							if (float.TryParse(array2[0], out var result3) && float.TryParse(array2[1], out var result4) && float.TryParse(array2[2], out var result5))
							{
								arg.x = result3;
								arg.y = result4;
								arg.z = result5;
							}
							else
							{
								Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
							}
						}
						else
						{
							Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
						}
						Networking.GetVector3(arg, array[2]);
						break;
					}
					case NetworkBroadcastDataType.BDlistString:
					{
						string[] source = array[1].Split(new char[1] { '\n' });
						Networking.GetListString(source.ToList(), array[2]);
						break;
					}
					}
					_ = LC_APIManager.netTester;
					return false;
				}
				Plugin.Log.LogError((object)"Generic Network receive fail. This is a failure of the API, and it should be reported as a bug.");
				Plugin.Log.LogError((object)$"Generic Network receive fail (expected 5+ data fragments, got {array.Length}). This is a failure of the API, and it should be reported as a bug.");
				return true;
			}
			if (!int.TryParse(array[4], out var result6))
			{
				Plugin.Log.LogWarning((object)("Failed to parse player ID '" + array[4] + "'!!"));
				return false;
			}
			if ((result6 == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
			{
				return false;
			}
			if (!Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result7))
			{
				Plugin.Log.LogError((object)("Unknown datatype - unable to parse '" + array[3] + "' into a known data type!"));
				return false;
			}
			switch (result7)
			{
			case NetworkBroadcastDataType.BDstring:
				Networking.GetString.InvokeActionSafe(array[1], array[2]);
				break;
			case NetworkBroadcastDataType.BDint:
				Networking.GetInt.InvokeActionSafe(int.Parse(array[1]), array[2]);
				break;
			case NetworkBroadcastDataType.BDfloat:
				Networking.GetFloat.InvokeActionSafe(float.Parse(array[1]), array[2]);
				break;
			case NetworkBroadcastDataType.BDvector3:
			{
				string text = array[1].Trim('(', ')');
				string[] array3 = text.Split(new char[1] { ',' });
				Vector3 param = default(Vector3);
				float result8;
				float result9;
				float result10;
				if (array3.Length != 3)
				{
					Plugin.Log.LogError((object)$"Vector3 Network receive fail (expected 3 numbers, got {array3.Length} number(?)(s) instead). This is a failure of the API, and it should be reported as a bug. (passing an empty Vector3 in its place)");
				}
				else if (float.TryParse(array3[0], out result8) && float.TryParse(array3[1], out result9) && float.TryParse(array3[2], out result10))
				{
					param.x = result8;
					param.y = result9;
					param.z = result10;
				}
				else
				{
					Plugin.Log.LogError((object)("Vector3 Network receive fail (failed to parse '" + text + "' as numbers). This is a failure of the API, and it should be reported as a bug."));
				}
				Networking.GetVector3.InvokeActionSafe(param, array[2]);
				break;
			}
			}
			_ = LC_APIManager.netTester;
			return false;
		}

		internal static bool ChatCommands(HUDManager __instance, CallbackContext context)
		{
			if (__instance.chatTextField.text.ToLower().Contains("/modcheck"))
			{
				CheatDatabase.OtherPlayerCheatDetector();
				return false;
			}
			return true;
		}
	}
}
namespace LC_API.GameInterfaceAPI
{
	public static class GameState
	{
		private static readonly Action NothingAction = delegate
		{
		};

		public static int AlivePlayerCount { get; private set; }

		public static ShipState ShipState { get; private set; }

		public static event Action PlayerDied;

		public static event Action LandOnMoon;

		public static event Action WentIntoOrbit;

		public static event Action ShipStartedLeaving;

		internal static void GSUpdate()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (StartOfRound.Instance.shipHasLanded && ShipState != ShipState.OnMoon)
				{
					ShipState = ShipState.OnMoon;
					GameState.LandOnMoon.InvokeActionSafe();
				}
				if (StartOfRound.Instance.inShipPhase && ShipState != 0)
				{
					ShipState = ShipState.InOrbit;
					GameState.WentIntoOrbit.InvokeActionSafe();
				}
				if (StartOfRound.Instance.shipIsLeaving && ShipState != ShipState.LeavingMoon)
				{
					ShipState = ShipState.LeavingMoon;
					GameState.ShipStartedLeaving.InvokeActionSafe();
				}
				if (AlivePlayerCount < StartOfRound.Instance.livingPlayers)
				{
					GameState.PlayerDied.InvokeActionSafe();
				}
				AlivePlayerCount = StartOfRound.Instance.livingPlayers;
			}
		}

		static GameState()
		{
			GameState.PlayerDied = NothingAction;
			GameState.LandOnMoon = NothingAction;
			GameState.WentIntoOrbit = NothingAction;
			GameState.ShipStartedLeaving = NothingAction;
		}
	}
	public class GameTips
	{
		private static List<string> tipHeaders = new List<string>();

		private static List<string> tipBodys = new List<string>();

		private static float lastMessageTime;

		public static void ShowTip(string header, string body)
		{
			tipHeaders.Add(header);
			tipBodys.Add(body);
		}

		public static void UpdateInternal()
		{
			lastMessageTime -= Time.deltaTime;
			if ((tipHeaders.Count > 0) & (lastMessageTime < 0f))
			{
				lastMessageTime = 5f;
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.DisplayTip(tipHeaders[0], tipBodys[0], false, false, "LC_Tip1");
				}
				tipHeaders.RemoveAt(0);
				tipBodys.RemoveAt(0);
			}
		}
	}
}
namespace LC_API.Extensions
{
	public static class DelegateExtensions
	{
		private static readonly PropertyInfo PluginGetLogger = AccessTools.Property(typeof(BaseUnityPlugin), "Logger");

		public static void InvokeActionSafe(this Action action)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action)@delegate)();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		public static void InvokeActionSafe<T>(this Action<T> action, T param)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action<T>)@delegate)(param);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		public static void InvokeActionSafe<T1, T2>(this Action<T1, T2> action, T1 param1, T2 param2)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((Action<T1, T2>)@delegate)(param1, param2);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}

		internal static void InvokeParameterlessDelegate<T>(this T paramlessDelegate) where T : Delegate
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if ((Delegate?)paramlessDelegate == (Delegate?)null)
			{
				return;
			}
			Delegate[] invocationList = paramlessDelegate.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					((T)@delegate).DynamicInvoke();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)"Exception while invoking hook callback!");
					string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
					PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
					if (val == null)
					{
						Plugin.Log.LogError((object)ex.ToString());
						break;
					}
					((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
				}
			}
		}
	}
}
namespace LC_API.Data
{
	internal enum NetworkBroadcastDataType
	{
		Unknown,
		BDint,
		BDfloat,
		BDvector3,
		BDstring,
		BDlistString
	}
	public enum ShipState
	{
		InOrbit,
		OnMoon,
		LeavingMoon
	}
}
namespace LC_API.Comp
{
	internal class LC_APIManager : MonoBehaviour
	{
		public static MenuManager MenuManager;

		public static bool netTester;

		private static int playerCount;

		private static bool wanttoCheckMods;

		private static float lobbychecktimer;

		public void Update()
		{
			GameState.GSUpdate();
			GameTips.UpdateInternal();
			if ((((Object)(object)HUDManager.Instance != (Object)null) & netTester) && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
			{
				Networking.Broadcast("testerData", "testerSignature");
			}
			if (!ModdedServer.setModdedOnly)
			{
				ModdedServer.OnSceneLoaded();
			}
			else if (ModdedServer.ModdedOnly && (Object)(object)MenuManager != (Object)null && Object.op_Implicit((Object)(object)MenuManager.versionNumberText))
			{
				((TMP_Text)MenuManager.versionNumberText).text = $"v{GameNetworkManager.Instance.gameVersionNum - 16440}\nMOD";
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				if (playerCount < GameNetworkManager.Instance.connectedPlayers)
				{
					lobbychecktimer = -4.5f;
					wanttoCheckMods = true;
				}
				playerCount = GameNetworkManager.Instance.connectedPlayers;
			}
			if (lobbychecktimer < 0f)
			{
				lobbychecktimer += Time.deltaTime;
			}
			else if (wanttoCheckMods)
			{
				wanttoCheckMods = false;
				CD();
			}
		}

		private void CD()
		{
			CheatDatabase.OtherPlayerCheatDetector();
		}
	}
}
namespace LC_API.BundleAPI
{
	public static class BundleLoader
	{
		[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
		public delegate void OnLoadedAssetsDelegate();

		[Obsolete("Use GetLoadedAsset instead. This will be removed/private in a future update.")]
		public static ConcurrentDictionary<string, Object> assets = new ConcurrentDictionary<string, Object>();

		[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
		public static OnLoadedAssetsDelegate OnLoadedAssets = LoadAssetsCompleted;

		public static bool AssetsInLegacyDirectory { get; private set; }

		public static bool LegacyLoadingEnabled { get; private set; }

		public static event Action OnLoadedBundles;

		internal static void Load(bool legacyLoading)
		{
			LegacyLoadingEnabled = legacyLoading;
			Plugin.Log.LogMessage((object)"BundleAPI will now load all asset bundles...");
			string path = Path.Combine(Paths.BepInExRootPath, "Bundles");
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
				Plugin.Log.LogMessage((object)"BundleAPI Created legacy bundle directory in BepInEx/Bundles");
			}
			string[] array = (from x in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
				where !x.EndsWith(".manifest", StringComparison.CurrentCultureIgnoreCase)
				select x).ToArray();
			AssetsInLegacyDirectory = array.Length != 0;
			if (!AssetsInLegacyDirectory)
			{
				Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from legacy directory");
			}
			if (AssetsInLegacyDirectory)
			{
				Plugin.Log.LogWarning((object)"The path BepInEx > Bundles is outdated and should not be used anymore! Bundles will be loaded from BepInEx > plugins from now on");
				LoadAllAssetsFromDirectory(array, legacyLoading);
			}
			path = Path.Combine(Paths.BepInExRootPath, "plugins");
			array = (from x in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
				where !x.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".json", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".png", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".md", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".old", StringComparison.CurrentCultureIgnoreCase)
				where !x.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase)
				select x).ToArray();
			if (array.Length == 0)
			{
				Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from plugins folder");
			}
			else
			{
				LoadAllAssetsFromDirectory(array, legacyLoading);
			}
			OnLoadedAssets.InvokeParameterlessDelegate();
			BundleLoader.OnLoadedBundles.InvokeActionSafe();
		}

		private static void LoadAllAssetsFromDirectory(string[] array, bool legacyLoading)
		{
			if (legacyLoading)
			{
				Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
				for (int i = 0; i < array.Length; i++)
				{
					try
					{
						SaveAsset(array[i], legacyLoading);
					}
					catch (Exception)
					{
						Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[i]));
					}
				}
				return;
			}
			Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
			for (int j = 0; j < array.Length; j++)
			{
				try
				{
					SaveAsset(array[j], legacyLoading);
				}
				catch (Exception)
				{
					Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[j]));
				}
			}
		}

		public static void SaveAsset(string path, bool legacyLoad)
		{
			AssetBundle val = AssetBundle.LoadFromFile(path);
			try
			{
				string[] allAssetNames = val.GetAllAssetNames();
				foreach (string text in allAssetNames)
				{
					Plugin.Log.LogMessage((object)("Got asset for load: " + text));
					Object val2 = val.LoadAsset(text);
					if (val2 == (Object)null)
					{
						Plugin.Log.LogWarning((object)$"Skipped/failed loading an asset (from bundle '{((Object)val).name}') - Asset path: {val2}");
						continue;
					}
					string key = (legacyLoad ? text.ToUpper() : text.ToLower());
					if (assets.ContainsKey(key))
					{
						Plugin.Log.LogError((object)"BundleAPI got duplicate asset!");
						break;
					}
					assets.TryAdd(key, val2);
					Plugin.Log.LogMessage((object)("Loaded asset: " + val2.name));
				}
			}
			finally
			{
				if (val != null)
				{
					val.Unload(false);
				}
			}
		}

		public static TAsset GetLoadedAsset<TAsset>(string itemPath) where TAsset : Object
		{
			Object value = null;
			if (LegacyLoadingEnabled)
			{
				assets.TryGetValue(itemPath.ToUpper(), out value);
			}
			if (value == (Object)null)
			{
				assets.TryGetValue(itemPath.ToLower(), out value);
			}
			return (TAsset)(object)value;
		}

		private static void LoadAssetsCompleted()
		{
			Plugin.Log.LogMessage((object)"BundleAPI finished loading all assets.");
		}

		static BundleLoader()
		{
			BundleLoader.OnLoadedBundles = LoadAssetsCompleted;
		}
	}
}

BepInEx/plugins/LethalBoykisserMod.dll

Decompiled 8 months ago
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.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance;
using GameNetcodeStuff;
using HarmonyLib;
using ModelReplacement;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalBoykisserMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalBoykisserMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1f1f2793-57ef-49c6-bca3-2205a4cd81a8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[AddComponentMenu("Dynamic Bone/Dynamic Bone")]
public class DynamicBone : MonoBehaviour
{
	public enum FreezeAxis
	{
		None,
		X,
		Y,
		Z
	}

	private class Particle
	{
		public Transform m_Transform = null;

		public int m_ParentIndex = -1;

		public float m_Damping = 0f;

		public float m_Elasticity = 0f;

		public float m_Stiffness = 0f;

		public float m_Inert = 0f;

		public float m_Radius = 0f;

		public float m_BoneLength = 0f;

		public Vector3 m_Position = Vector3.zero;

		public Vector3 m_PrevPosition = Vector3.zero;

		public Vector3 m_EndOffset = Vector3.zero;

		public Vector3 m_InitLocalPosition = Vector3.zero;

		public Quaternion m_InitLocalRotation = Quaternion.identity;
	}

	public Transform m_Root = null;

	public float m_UpdateRate = 60f;

	[Range(0f, 1f)]
	public float m_Damping = 0.1f;

	public AnimationCurve m_DampingDistrib = null;

	[Range(0f, 1f)]
	public float m_Elasticity = 0.1f;

	public AnimationCurve m_ElasticityDistrib = null;

	[Range(0f, 1f)]
	public float m_Stiffness = 0.1f;

	public AnimationCurve m_StiffnessDistrib = null;

	[Range(0f, 1f)]
	public float m_Inert = 0f;

	public AnimationCurve m_InertDistrib = null;

	public float m_Radius = 0f;

	public AnimationCurve m_RadiusDistrib = null;

	public float m_EndLength = 0f;

	public Vector3 m_EndOffset = Vector3.zero;

	public Vector3 m_Gravity = Vector3.zero;

	public Vector3 m_Force = Vector3.zero;

	public List<DynamicBoneCollider> m_Colliders = null;

	public List<Transform> m_Exclusions = null;

	public FreezeAxis m_FreezeAxis = FreezeAxis.None;

	public bool m_DistantDisable = false;

	public Transform m_ReferenceObject = null;

	public float m_DistanceToObject = 20f;

	private Vector3 m_LocalGravity = Vector3.zero;

	private Vector3 m_ObjectMove = Vector3.zero;

	private Vector3 m_ObjectPrevPosition = Vector3.zero;

	private float m_BoneTotalLength = 0f;

	private float m_ObjectScale = 1f;

	private float m_Time = 0f;

	private float m_Weight = 1f;

	private bool m_DistantDisabled = false;

	private List<Particle> m_Particles = new List<Particle>();

	private void Start()
	{
		SetupParticles();
	}

	private void Update()
	{
		if (m_Weight > 0f && (!m_DistantDisable || !m_DistantDisabled))
		{
			InitTransforms();
		}
	}

	private void LateUpdate()
	{
		if (m_DistantDisable)
		{
			CheckDistance();
		}
		if (m_Weight > 0f && (!m_DistantDisable || !m_DistantDisabled))
		{
			UpdateDynamicBones(Time.deltaTime);
		}
	}

	private void CheckDistance()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//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_0059: Unknown result type (might be due to invalid IL or missing references)
		Transform val = m_ReferenceObject;
		if ((Object)(object)val == (Object)null && (Object)(object)Camera.main != (Object)null)
		{
			val = ((Component)Camera.main).transform;
		}
		if (!((Object)(object)val != (Object)null))
		{
			return;
		}
		Vector3 val2 = val.position - ((Component)this).transform.position;
		float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
		bool flag = sqrMagnitude > m_DistanceToObject * m_DistanceToObject;
		if (flag != m_DistantDisabled)
		{
			if (!flag)
			{
				ResetParticlesPosition();
			}
			m_DistantDisabled = flag;
		}
	}

	private void OnEnable()
	{
		ResetParticlesPosition();
	}

	private void OnDisable()
	{
		InitTransforms();
	}

	private void OnValidate()
	{
		m_UpdateRate = Mathf.Max(m_UpdateRate, 0f);
		m_Damping = Mathf.Clamp01(m_Damping);
		m_Elasticity = Mathf.Clamp01(m_Elasticity);
		m_Stiffness = Mathf.Clamp01(m_Stiffness);
		m_Inert = Mathf.Clamp01(m_Inert);
		m_Radius = Mathf.Max(m_Radius, 0f);
		if (Application.isEditor && Application.isPlaying)
		{
			InitTransforms();
			SetupParticles();
		}
	}

	private void OnDrawGizmosSelected()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (!((Behaviour)this).enabled || (Object)(object)m_Root == (Object)null)
		{
			return;
		}
		if (Application.isEditor && !Application.isPlaying && ((Component)this).transform.hasChanged)
		{
			InitTransforms();
			SetupParticles();
		}
		Gizmos.color = Color.white;
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			if (particle.m_ParentIndex >= 0)
			{
				Particle particle2 = m_Particles[particle.m_ParentIndex];
				Gizmos.DrawLine(particle.m_Position, particle2.m_Position);
			}
			if (particle.m_Radius > 0f)
			{
				Gizmos.DrawWireSphere(particle.m_Position, particle.m_Radius * m_ObjectScale);
			}
		}
	}

	public void SetWeight(float w)
	{
		if (m_Weight != w)
		{
			if (w == 0f)
			{
				InitTransforms();
			}
			else if (m_Weight == 0f)
			{
				ResetParticlesPosition();
			}
			m_Weight = w;
		}
	}

	public float GetWeight()
	{
		return m_Weight;
	}

	private void UpdateDynamicBones(float t)
	{
		//IL_001e: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_Root == (Object)null)
		{
			return;
		}
		m_ObjectScale = Mathf.Abs(((Component)this).transform.lossyScale.x);
		m_ObjectMove = ((Component)this).transform.position - m_ObjectPrevPosition;
		m_ObjectPrevPosition = ((Component)this).transform.position;
		int num = 1;
		if (m_UpdateRate > 0f)
		{
			float num2 = 1f / m_UpdateRate;
			m_Time += t;
			num = 0;
			while (m_Time >= num2)
			{
				m_Time -= num2;
				if (++num >= 3)
				{
					m_Time = 0f;
					break;
				}
			}
		}
		if (num > 0)
		{
			for (int i = 0; i < num; i++)
			{
				UpdateParticles1();
				UpdateParticles2();
				m_ObjectMove = Vector3.zero;
			}
		}
		else
		{
			SkipUpdateParticles();
		}
		ApplyParticlesToTransforms();
	}

	private void SetupParticles()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//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)
		//IL_0062: 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)
		m_Particles.Clear();
		if ((Object)(object)m_Root == (Object)null)
		{
			return;
		}
		m_LocalGravity = m_Root.InverseTransformDirection(m_Gravity);
		m_ObjectScale = ((Component)this).transform.lossyScale.x;
		m_ObjectPrevPosition = ((Component)this).transform.position;
		m_ObjectMove = Vector3.zero;
		m_BoneTotalLength = 0f;
		AppendParticles(m_Root, -1, 0f);
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			particle.m_Damping = m_Damping;
			particle.m_Elasticity = m_Elasticity;
			particle.m_Stiffness = m_Stiffness;
			particle.m_Inert = m_Inert;
			particle.m_Radius = m_Radius;
			if (m_BoneTotalLength > 0f)
			{
				float num = particle.m_BoneLength / m_BoneTotalLength;
				if (m_DampingDistrib != null && m_DampingDistrib.keys.Length != 0)
				{
					particle.m_Damping *= m_DampingDistrib.Evaluate(num);
				}
				if (m_ElasticityDistrib != null && m_ElasticityDistrib.keys.Length != 0)
				{
					particle.m_Elasticity *= m_ElasticityDistrib.Evaluate(num);
				}
				if (m_StiffnessDistrib != null && m_StiffnessDistrib.keys.Length != 0)
				{
					particle.m_Stiffness *= m_StiffnessDistrib.Evaluate(num);
				}
				if (m_InertDistrib != null && m_InertDistrib.keys.Length != 0)
				{
					particle.m_Inert *= m_InertDistrib.Evaluate(num);
				}
				if (m_RadiusDistrib != null && m_RadiusDistrib.keys.Length != 0)
				{
					particle.m_Radius *= m_RadiusDistrib.Evaluate(num);
				}
			}
			particle.m_Damping = Mathf.Clamp01(particle.m_Damping);
			particle.m_Elasticity = Mathf.Clamp01(particle.m_Elasticity);
			particle.m_Stiffness = Mathf.Clamp01(particle.m_Stiffness);
			particle.m_Inert = Mathf.Clamp01(particle.m_Inert);
			particle.m_Radius = Mathf.Max(particle.m_Radius, 0f);
		}
	}

	private void AppendParticles(Transform b, int parentIndex, float boneLength)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: 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_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: 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_012f: 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)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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)
		Particle particle = new Particle();
		particle.m_Transform = b;
		particle.m_ParentIndex = parentIndex;
		Vector3 val;
		if ((Object)(object)b != (Object)null)
		{
			val = (particle.m_Position = (particle.m_PrevPosition = b.position));
			particle.m_InitLocalPosition = b.localPosition;
			particle.m_InitLocalRotation = b.localRotation;
		}
		else
		{
			Transform transform = m_Particles[parentIndex].m_Transform;
			if (m_EndLength > 0f)
			{
				Transform parent = transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					particle.m_EndOffset = transform.InverseTransformPoint(transform.position * 2f - parent.position) * m_EndLength;
				}
				else
				{
					particle.m_EndOffset = new Vector3(m_EndLength, 0f, 0f);
				}
			}
			else
			{
				particle.m_EndOffset = transform.InverseTransformPoint(((Component)this).transform.TransformDirection(m_EndOffset) + transform.position);
			}
			val = (particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset)));
		}
		if (parentIndex >= 0)
		{
			float num = boneLength;
			val = m_Particles[parentIndex].m_Transform.position - particle.m_Position;
			boneLength = num + ((Vector3)(ref val)).magnitude;
			particle.m_BoneLength = boneLength;
			m_BoneTotalLength = Mathf.Max(m_BoneTotalLength, boneLength);
		}
		int count = m_Particles.Count;
		m_Particles.Add(particle);
		if (!((Object)(object)b != (Object)null))
		{
			return;
		}
		for (int i = 0; i < b.childCount; i++)
		{
			bool flag = false;
			if (m_Exclusions != null)
			{
				for (int j = 0; j < m_Exclusions.Count; j++)
				{
					Transform val2 = m_Exclusions[j];
					if ((Object)(object)val2 == (Object)(object)b.GetChild(i))
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				AppendParticles(b.GetChild(i), count, boneLength);
			}
		}
		if (b.childCount == 0 && (m_EndLength > 0f || m_EndOffset != Vector3.zero))
		{
			AppendParticles(null, count, boneLength);
		}
	}

	private void InitTransforms()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			if ((Object)(object)particle.m_Transform != (Object)null)
			{
				particle.m_Transform.localPosition = particle.m_InitLocalPosition;
				particle.m_Transform.localRotation = particle.m_InitLocalRotation;
			}
		}
	}

	private void ResetParticlesPosition()
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			if ((Object)(object)particle.m_Transform != (Object)null)
			{
				particle.m_Position = (particle.m_PrevPosition = particle.m_Transform.position);
				continue;
			}
			Transform transform = m_Particles[particle.m_ParentIndex].m_Transform;
			particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset));
		}
		m_ObjectPrevPosition = ((Component)this).transform.position;
	}

	private void UpdateParticles1()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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)
		//IL_0013: 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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_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_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
		Vector3 gravity = m_Gravity;
		Vector3 normalized = ((Vector3)(ref m_Gravity)).normalized;
		Vector3 val = m_Root.TransformDirection(m_LocalGravity);
		Vector3 val2 = normalized * Mathf.Max(Vector3.Dot(val, normalized), 0f);
		gravity -= val2;
		gravity = (gravity + m_Force) * m_ObjectScale;
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			if (particle.m_ParentIndex >= 0)
			{
				Vector3 val3 = particle.m_Position - particle.m_PrevPosition;
				Vector3 val4 = m_ObjectMove * particle.m_Inert;
				particle.m_PrevPosition = particle.m_Position + val4;
				particle.m_Position += val3 * (1f - particle.m_Damping) + gravity + val4;
			}
			else
			{
				particle.m_PrevPosition = particle.m_Position;
				particle.m_Position = particle.m_Transform.position;
			}
		}
	}

	private void UpdateParticles2()
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//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_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: 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_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: 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_0123: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d7: 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_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		Plane val = default(Plane);
		for (int i = 1; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			Particle particle2 = m_Particles[particle.m_ParentIndex];
			Vector3 val2;
			float magnitude;
			if ((Object)(object)particle.m_Transform != (Object)null)
			{
				val2 = particle2.m_Transform.position - particle.m_Transform.position;
				magnitude = ((Vector3)(ref val2)).magnitude;
			}
			else
			{
				Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix;
				val2 = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyVector(particle.m_EndOffset);
				magnitude = ((Vector3)(ref val2)).magnitude;
			}
			float num = magnitude;
			float num2 = Mathf.Lerp(1f, particle.m_Stiffness, m_Weight);
			if (num2 > 0f || particle.m_Elasticity > 0f)
			{
				Matrix4x4 localToWorldMatrix2 = particle2.m_Transform.localToWorldMatrix;
				((Matrix4x4)(ref localToWorldMatrix2)).SetColumn(3, Vector4.op_Implicit(particle2.m_Position));
				Vector3 val3 = ((!((Object)(object)particle.m_Transform != (Object)null)) ? ((Matrix4x4)(ref localToWorldMatrix2)).MultiplyPoint3x4(particle.m_EndOffset) : ((Matrix4x4)(ref localToWorldMatrix2)).MultiplyPoint3x4(particle.m_Transform.localPosition));
				Vector3 val4 = val3 - particle.m_Position;
				particle.m_Position += val4 * particle.m_Elasticity;
				if (num2 > 0f)
				{
					val4 = val3 - particle.m_Position;
					float magnitude2 = ((Vector3)(ref val4)).magnitude;
					float num3 = num * (1f - num2) * 2f;
					if (magnitude2 > num3)
					{
						particle.m_Position += val4 * ((magnitude2 - num3) / magnitude2);
					}
				}
			}
			if (m_Colliders != null)
			{
				float particleRadius = particle.m_Radius * m_ObjectScale;
				for (int j = 0; j < m_Colliders.Count; j++)
				{
					DynamicBoneCollider dynamicBoneCollider = m_Colliders[j];
					if ((Object)(object)dynamicBoneCollider != (Object)null && ((Behaviour)dynamicBoneCollider).enabled)
					{
						dynamicBoneCollider.Collide(ref particle.m_Position, particleRadius);
					}
				}
			}
			if (m_FreezeAxis != 0)
			{
				switch (m_FreezeAxis)
				{
				case FreezeAxis.X:
					((Plane)(ref val)).SetNormalAndPosition(particle2.m_Transform.right, particle2.m_Position);
					break;
				case FreezeAxis.Y:
					((Plane)(ref val)).SetNormalAndPosition(particle2.m_Transform.up, particle2.m_Position);
					break;
				case FreezeAxis.Z:
					((Plane)(ref val)).SetNormalAndPosition(particle2.m_Transform.forward, particle2.m_Position);
					break;
				}
				particle.m_Position -= ((Plane)(ref val)).normal * ((Plane)(ref val)).GetDistanceToPoint(particle.m_Position);
			}
			Vector3 val5 = particle2.m_Position - particle.m_Position;
			float magnitude3 = ((Vector3)(ref val5)).magnitude;
			if (magnitude3 > 0f)
			{
				particle.m_Position += val5 * ((magnitude3 - num) / magnitude3);
			}
		}
	}

	private void SkipUpdateParticles()
	{
		//IL_01fb: 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_020c: 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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: 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_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: 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_014b: 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_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			if (particle.m_ParentIndex >= 0)
			{
				Vector3 val = m_ObjectMove * particle.m_Inert;
				particle.m_PrevPosition += val;
				particle.m_Position += val;
				Particle particle2 = m_Particles[particle.m_ParentIndex];
				Vector3 val2;
				float magnitude;
				if ((Object)(object)particle.m_Transform != (Object)null)
				{
					val2 = particle2.m_Transform.position - particle.m_Transform.position;
					magnitude = ((Vector3)(ref val2)).magnitude;
				}
				else
				{
					Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix;
					val2 = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyVector(particle.m_EndOffset);
					magnitude = ((Vector3)(ref val2)).magnitude;
				}
				float num = magnitude;
				float num2 = Mathf.Lerp(1f, particle.m_Stiffness, m_Weight);
				if (num2 > 0f)
				{
					Matrix4x4 localToWorldMatrix2 = particle2.m_Transform.localToWorldMatrix;
					((Matrix4x4)(ref localToWorldMatrix2)).SetColumn(3, Vector4.op_Implicit(particle2.m_Position));
					Vector3 val3 = ((!((Object)(object)particle.m_Transform != (Object)null)) ? ((Matrix4x4)(ref localToWorldMatrix2)).MultiplyPoint3x4(particle.m_EndOffset) : ((Matrix4x4)(ref localToWorldMatrix2)).MultiplyPoint3x4(particle.m_Transform.localPosition));
					Vector3 val4 = val3 - particle.m_Position;
					float magnitude2 = ((Vector3)(ref val4)).magnitude;
					float num3 = num * (1f - num2) * 2f;
					if (magnitude2 > num3)
					{
						particle.m_Position += val4 * ((magnitude2 - num3) / magnitude2);
					}
				}
				Vector3 val5 = particle2.m_Position - particle.m_Position;
				float magnitude3 = ((Vector3)(ref val5)).magnitude;
				if (magnitude3 > 0f)
				{
					particle.m_Position += val5 * ((magnitude3 - num) / magnitude3);
				}
			}
			else
			{
				particle.m_PrevPosition = particle.m_Position;
				particle.m_Position = particle.m_Transform.position;
			}
		}
	}

	private void ApplyParticlesToTransforms()
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 1; i < m_Particles.Count; i++)
		{
			Particle particle = m_Particles[i];
			Particle particle2 = m_Particles[particle.m_ParentIndex];
			if (particle2.m_Transform.childCount <= 1)
			{
				Vector3 val = ((!((Object)(object)particle.m_Transform != (Object)null)) ? particle.m_EndOffset : particle.m_Transform.localPosition);
				Quaternion val2 = Quaternion.FromToRotation(particle2.m_Transform.TransformDirection(val), particle.m_Position - particle2.m_Position);
				particle2.m_Transform.rotation = val2 * particle2.m_Transform.rotation;
			}
			if ((Object)(object)particle.m_Transform != (Object)null)
			{
				particle.m_Transform.position = particle.m_Position;
			}
		}
	}
}
[AddComponentMenu("Dynamic Bone/Dynamic Bone Collider")]
public class DynamicBoneCollider : MonoBehaviour
{
	public enum Direction
	{
		X,
		Y,
		Z
	}

	public enum Bound
	{
		Outside,
		Inside
	}

	public Vector3 m_Center = Vector3.zero;

	public float m_Radius = 0.5f;

	public float m_Height = 0f;

	public Direction m_Direction = Direction.X;

	public Bound m_Bound = Bound.Outside;

	private void OnValidate()
	{
		m_Radius = Mathf.Max(m_Radius, 0f);
		m_Height = Mathf.Max(m_Height, 0f);
	}

	public void Collide(ref Vector3 particlePosition, float particleRadius)
	{
		//IL_000d: 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_0093: 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_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: 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_012f: Unknown result type (might be due to invalid IL or missing references)
		float num = m_Radius * Mathf.Abs(((Component)this).transform.lossyScale.x);
		float num2 = m_Height * 0.5f - num;
		if (num2 <= 0f)
		{
			if (m_Bound == Bound.Outside)
			{
				OutsideSphere(ref particlePosition, particleRadius, ((Component)this).transform.TransformPoint(m_Center), num);
			}
			else
			{
				InsideSphere(ref particlePosition, particleRadius, ((Component)this).transform.TransformPoint(m_Center), num);
			}
			return;
		}
		Vector3 center = m_Center;
		Vector3 center2 = m_Center;
		switch (m_Direction)
		{
		case Direction.X:
			center.x -= num2;
			center2.x += num2;
			break;
		case Direction.Y:
			center.y -= num2;
			center2.y += num2;
			break;
		case Direction.Z:
			center.z -= num2;
			center2.z += num2;
			break;
		}
		if (m_Bound == Bound.Outside)
		{
			OutsideCapsule(ref particlePosition, particleRadius, ((Component)this).transform.TransformPoint(center), ((Component)this).transform.TransformPoint(center2), num);
		}
		else
		{
			InsideCapsule(ref particlePosition, particleRadius, ((Component)this).transform.TransformPoint(center), ((Component)this).transform.TransformPoint(center2), num);
		}
	}

	private static void OutsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		float num = sphereRadius + particleRadius;
		float num2 = num * num;
		Vector3 val = particlePosition - sphereCenter;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		if (sqrMagnitude > 0f && sqrMagnitude < num2)
		{
			float num3 = Mathf.Sqrt(sqrMagnitude);
			particlePosition = sphereCenter + val * (num / num3);
		}
	}

	private static void InsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//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)
		float num = sphereRadius + particleRadius;
		float num2 = num * num;
		Vector3 val = particlePosition - sphereCenter;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		if (sqrMagnitude > num2)
		{
			float num3 = Mathf.Sqrt(sqrMagnitude);
			particlePosition = sphereCenter + val * (num / num3);
		}
	}

	private static void OutsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
	{
		//IL_000a: 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)
		//IL_0011: 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)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: 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_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		float num = capsuleRadius + particleRadius;
		float num2 = num * num;
		Vector3 val = capsuleP1 - capsuleP0;
		Vector3 val2 = particlePosition - capsuleP0;
		float num3 = Vector3.Dot(val2, val);
		if (num3 <= 0f)
		{
			float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude > 0f && sqrMagnitude < num2)
			{
				float num4 = Mathf.Sqrt(sqrMagnitude);
				particlePosition = capsuleP0 + val2 * (num / num4);
			}
			return;
		}
		float sqrMagnitude2 = ((Vector3)(ref val)).sqrMagnitude;
		if (num3 >= sqrMagnitude2)
		{
			val2 = particlePosition - capsuleP1;
			float sqrMagnitude3 = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude3 > 0f && sqrMagnitude3 < num2)
			{
				float num5 = Mathf.Sqrt(sqrMagnitude3);
				particlePosition = capsuleP1 + val2 * (num / num5);
			}
		}
		else if (sqrMagnitude2 > 0f)
		{
			num3 /= sqrMagnitude2;
			val2 -= val * num3;
			float sqrMagnitude4 = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude4 > 0f && sqrMagnitude4 < num2)
			{
				float num6 = Mathf.Sqrt(sqrMagnitude4);
				particlePosition += val2 * ((num - num6) / num6);
			}
		}
	}

	private static void InsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
	{
		//IL_000a: 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)
		//IL_0011: 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)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: 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_0126: 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_0130: Unknown result type (might be due to invalid IL or missing references)
		float num = capsuleRadius + particleRadius;
		float num2 = num * num;
		Vector3 val = capsuleP1 - capsuleP0;
		Vector3 val2 = particlePosition - capsuleP0;
		float num3 = Vector3.Dot(val2, val);
		if (num3 <= 0f)
		{
			float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude > num2)
			{
				float num4 = Mathf.Sqrt(sqrMagnitude);
				particlePosition = capsuleP0 + val2 * (num / num4);
			}
			return;
		}
		float sqrMagnitude2 = ((Vector3)(ref val)).sqrMagnitude;
		if (num3 >= sqrMagnitude2)
		{
			val2 = particlePosition - capsuleP1;
			float sqrMagnitude3 = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude3 > num2)
			{
				float num5 = Mathf.Sqrt(sqrMagnitude3);
				particlePosition = capsuleP1 + val2 * (num / num5);
			}
		}
		else if (sqrMagnitude2 > 0f)
		{
			num3 /= sqrMagnitude2;
			val2 -= val * num3;
			float sqrMagnitude4 = ((Vector3)(ref val2)).sqrMagnitude;
			if (sqrMagnitude4 > num2)
			{
				float num6 = Mathf.Sqrt(sqrMagnitude4);
				particlePosition += val2 * ((num - num6) / num6);
			}
		}
	}

	private void OnDrawGizmosSelected()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: 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_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		if (!((Behaviour)this).enabled)
		{
			return;
		}
		if (m_Bound == Bound.Outside)
		{
			Gizmos.color = Color.yellow;
		}
		else
		{
			Gizmos.color = Color.magenta;
		}
		float num = m_Radius * Mathf.Abs(((Component)this).transform.lossyScale.x);
		float num2 = m_Height * 0.5f - num;
		if (num2 <= 0f)
		{
			Gizmos.DrawWireSphere(((Component)this).transform.TransformPoint(m_Center), num);
			return;
		}
		Vector3 center = m_Center;
		Vector3 center2 = m_Center;
		switch (m_Direction)
		{
		case Direction.X:
			center.x -= num2;
			center2.x += num2;
			break;
		case Direction.Y:
			center.y -= num2;
			center2.y += num2;
			break;
		case Direction.Z:
			center.z -= num2;
			center2.z += num2;
			break;
		}
		Gizmos.DrawWireSphere(((Component)this).transform.TransformPoint(center), num);
		Gizmos.DrawWireSphere(((Component)this).transform.TransformPoint(center2), num);
	}
}
namespace LethalBoykisserMod;

public static class Assets
{
	public static string mainAssetBundleName = "boykisserbundle";

	public static AssetBundle MainAssetBundle = null;

	private static string GetAssemblyName()
	{
		return Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];
	}

	public static void PopulateAssets()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		if ((Object)MainAssetBundle == (Object)null)
		{
			Debug.Log((object)Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName));
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName);
			MainAssetBundle = AssetBundle.LoadFromStream(stream);
		}
	}
}
public class BodyReplacementBoy : BodyReplacementBase
{
	protected override GameObject LoadAssetsAndReturnModel()
	{
		string text = "boykisserprefab";
		return Assets.MainAssetBundle.LoadAsset<GameObject>(text);
	}

	protected override void AddModelScripts()
	{
		Debug.Log((object)("Running " + ((Object)base.replacementModel).name));
		PlayerControllerB component = ((Component)this).gameObject.GetComponent<PlayerControllerB>();
		Transform val = (from x in base.replacementModel.GetComponentsInChildren<Transform>()
			where ((Object)x).name.Contains("Body")
			select x).FirstOrDefault();
		if ((Object)(object)((Component)val).gameObject.GetComponent<ExpressionManager>() != (Object)null)
		{
			Debug.Log((object)"you're not supposed to be here");
			((Component)val).gameObject.GetComponent<ExpressionManager>().bodyReplacementB = ((Component)this).gameObject.GetComponent<BodyReplacementBoy>();
		}
		else
		{
			((Component)val).gameObject.AddComponent<ExpressionManager>();
			ExpressionManager component2 = ((Component)val).GetComponent<ExpressionManager>();
			component2.bodyReplacementB = ((Component)this).gameObject.GetComponent<BodyReplacementBoy>();
		}
		Transform where = (from x in base.replacementModel.GetComponentsInChildren<Transform>()
			where ((Object)x).name.Contains("Tail_001")
			select x).FirstOrDefault();
		Transform where2 = (from x in base.replacementModel.GetComponentsInChildren<Transform>()
			where ((Object)x).name.Contains("Ear_L")
			select x).FirstOrDefault();
		Transform where3 = (from x in base.replacementModel.GetComponentsInChildren<Transform>()
			where ((Object)x).name.Contains("Ear_R")
			select x).FirstOrDefault();
		CreateBone(where, colldier: false, ear: true);
		CreateBone(where2, colldier: false, ear: true);
		CreateBone(where3, colldier: false, ear: true);
	}

	private void CreateBone(Transform where, bool colldier = false, bool ear = false)
	{
		if (!Object.op_Implicit((Object)(object)((Component)where).gameObject.GetComponent<DynamicBone>()))
		{
			DynamicBone dynamicBone = ((Component)where).gameObject.AddComponent<DynamicBone>();
			dynamicBone.m_Root = where;
			if (colldier)
			{
				DynamicBoneCollider dynamicBoneCollider = ((Component)where).gameObject.AddComponent<DynamicBoneCollider>();
			}
			if (ear)
			{
				EarSettings(dynamicBone);
			}
		}
	}

	private void EarSettings(DynamicBone ear)
	{
		ear.m_UpdateRate = 70f;
		ear.m_Damping = 0.2f;
		ear.m_Elasticity = 0.1f;
		ear.m_Stiffness = 0.035f;
		ear.m_Inert = 0.555f;
	}

	public PlayerControllerB TryGetPlayerController()
	{
		return ((Component)this).gameObject.GetComponent<PlayerControllerB>();
	}

	public GameObject getDeadBody()
	{
		return base.replacementDeadBody;
	}
}
public class ExpressionManager : MonoBehaviour
{
	private enum BlinkShapes
	{
		Blink = 52,
		Scream
	}

	private enum SpeakShapes
	{
		Mouth = 57
	}

	private enum voicestate
	{
		Closed,
		Talking,
		Screaming
	}

	private SkinnedMeshRenderer body;

	private IEnumerator blinkingInstance;

	private IEnumerator speakingInstance;

	private bool isblinking;

	private GameObject parent;

	private PlayerControllerB plrCntrB;

	public BodyReplacementBoy bodyReplacementB;

	private bool isScreaming;

	private voicestate currentVoiceState;

	private bool eyeOpen = true;

	public bool died = false;

	private VoicePlayerState vps;

	private IEnumerator currentBlinkState;

	private IEnumerator currentSpeakState;

	private void Awake()
	{
		plrCntrB = bodyReplacementB.TryGetPlayerController();
		body = ((Component)this).gameObject.GetComponent<SkinnedMeshRenderer>();
		parent = ((Component)((Component)this).gameObject.transform.parent).gameObject;
		if (!plrCntrB.isPlayerDead && died)
		{
			died = false;
			OnRespawn();
		}
	}

	private void OnEnable()
	{
		plrCntrB = bodyReplacementB.TryGetPlayerController();
		if (!plrCntrB.isPlayerDead)
		{
			if (died)
			{
				died = false;
				OnRespawn();
			}
			if (blinkingInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(blinkingInstance);
			}
			if (speakingInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(speakingInstance);
			}
			body.SetBlendShapeWeight(52, 0f);
			body.SetBlendShapeWeight(53, 0f);
			body.SetBlendShapeWeight(57, 0f);
			eyeOpen = true;
			isblinking = false;
			isScreaming = false;
		}
	}

	private void Update()
	{
		if (!isblinking && (Object)(object)body != (Object)null && !died && !isScreaming)
		{
			isblinking = true;
			if (blinkingInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(blinkingInstance);
			}
			eyeOpen = !eyeOpen;
			blinkingInstance = changeBlinkState(BlinkShapes.Blink, EyeStateVal(eyeOpen), blinkingInstance);
			((MonoBehaviour)this).StartCoroutine(blinkingInstance);
		}
		if (plrCntrB.voicePlayerState != null)
		{
			vps = plrCntrB.voicePlayerState;
			if (vps.IsSpeaking)
			{
				if (LethalBoykisserBase.playerScreams.Value)
				{
					if (voiceAmp() > 80f && !isScreaming)
					{
						((MonoBehaviour)this).StartCoroutine(ChangeScreamState(screaming: true));
					}
					if (voiceAmp() < 80f && isScreaming)
					{
						((MonoBehaviour)this).StartCoroutine(ChangeScreamState(screaming: false));
					}
				}
				if (voiceAmp() > 5f && currentVoiceState != voicestate.Talking)
				{
					currentVoiceState = voicestate.Talking;
					if (speakingInstance != null)
					{
						((MonoBehaviour)this).StopCoroutine(speakingInstance);
					}
					speakingInstance = changeSpeakState(SpeakShapes.Mouth, 50, speakingInstance);
					((MonoBehaviour)this).StartCoroutine(speakingInstance);
				}
				if (voiceAmp() < 5f && currentVoiceState != 0)
				{
					currentVoiceState = voicestate.Closed;
					if (speakingInstance != null)
					{
						((MonoBehaviour)this).StopCoroutine(speakingInstance);
					}
					speakingInstance = changeSpeakState(SpeakShapes.Mouth, 0, speakingInstance);
					((MonoBehaviour)this).StartCoroutine(speakingInstance);
				}
			}
		}
		if (plrCntrB.isPlayerDead && !died)
		{
			died = true;
			OnDeath();
		}
		if (!plrCntrB.isPlayerDead && died)
		{
			died = false;
			OnRespawn();
			if (blinkingInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(blinkingInstance);
			}
			if (speakingInstance != null)
			{
				((MonoBehaviour)this).StopCoroutine(speakingInstance);
			}
			body.SetBlendShapeWeight(52, 0f);
			body.SetBlendShapeWeight(53, 0f);
			body.SetBlendShapeWeight(57, 0f);
			eyeOpen = true;
			isblinking = false;
			isScreaming = false;
		}
	}

	private void OnDeath()
	{
		((MonoBehaviour)this).StopAllCoroutines();
		GameObject deadBody = bodyReplacementB.getDeadBody();
		SkinnedMeshRenderer val = (from x in deadBody.GetComponentsInChildren<SkinnedMeshRenderer>()
			where ((Object)x).name.Contains("Body")
			select x).FirstOrDefault();
		((Behaviour)((Component)val).gameObject.GetComponent<ExpressionManager>()).enabled = false;
		val.SetBlendShapeWeight(52, 0f);
		val.SetBlendShapeWeight(72, 100f);
		val.SetBlendShapeWeight(30, 0f);
	}

	private void OnRespawn()
	{
		isblinking = false;
		body.SetBlendShapeWeight(72, 0f);
		body.SetBlendShapeWeight(30, 100f);
	}

	private IEnumerator ChangeScreamState(bool screaming)
	{
		isblinking = true;
		isScreaming = screaming;
		body.SetBlendShapeWeight(52, 0f);
		if (blinkingInstance != null)
		{
			((MonoBehaviour)this).StopCoroutine(blinkingInstance);
		}
		blinkingInstance = changeBlinkState(BlinkShapes.Scream, EyeStateVal(!isScreaming), blinkingInstance, 0.03f);
		yield return ((MonoBehaviour)this).StartCoroutine(blinkingInstance);
		if (!isScreaming)
		{
			isblinking = false;
		}
	}

	private IEnumerator changeBlinkState(BlinkShapes state, int value, IEnumerator instance, float speed = 0.15f)
	{
		if (died)
		{
			yield break;
		}
		if (currentBlinkState != null)
		{
			((MonoBehaviour)this).StopCoroutine(currentBlinkState);
		}
		currentBlinkState = instance;
		float elapsedTime = 0f;
		while (body.GetBlendShapeWeight((int)state) != (float)value)
		{
			elapsedTime += Time.deltaTime;
			float percComplete = elapsedTime / speed;
			float blendKey = Mathf.Lerp(body.GetBlendShapeWeight((int)state), (float)value, percComplete);
			body.SetBlendShapeWeight((int)state, blendKey);
			yield return (object)new WaitForSeconds(0.01f);
		}
		body.SetBlendShapeWeight((int)state, (float)value);
		yield return (object)new WaitForSeconds(0.25f);
		currentBlinkState = null;
		if (state == BlinkShapes.Blink)
		{
			if ((float)value == 0f)
			{
				yield return (object)new WaitForSeconds(Random.Range(1f, 4f));
				isblinking = false;
			}
			else
			{
				isblinking = false;
			}
		}
	}

	private IEnumerator changeSpeakState(SpeakShapes state, int value, IEnumerator instance, float speed = 0.035f)
	{
		if (!died)
		{
			if (currentSpeakState != null)
			{
				((MonoBehaviour)this).StopCoroutine(currentSpeakState);
			}
			currentSpeakState = instance;
			float elapsedTime = 0f;
			while (body.GetBlendShapeWeight((int)state) != (float)value)
			{
				elapsedTime += Time.deltaTime;
				float percComplete = elapsedTime / speed;
				float blendKey = Mathf.Lerp(body.GetBlendShapeWeight((int)state), (float)value, percComplete);
				body.SetBlendShapeWeight((int)state, blendKey);
				yield return (object)new WaitForSeconds(0.01f);
			}
			body.SetBlendShapeWeight((int)state, (float)value);
			currentSpeakState = null;
		}
	}

	private int EyeStateVal(bool state)
	{
		if (state)
		{
			return 0;
		}
		return 100;
	}

	private float voiceAmp()
	{
		return vps.Amplitude * 6.5f * 100f;
	}
}
[BepInPlugin("LethallyGay.Boykisser", "Boy Kisser Model", "0.0.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class LethalBoykisserBase : BaseUnityPlugin
{
	public static ConfigFile config;

	private const string modGUID = "LethallyGay.Boykisser";

	private const string modNAME = "Boy Kisser Model";

	private const string modVER = "0.0.0.1";

	private readonly Harmony harmony = new Harmony("LethallyGay.Boykisser");

	private static LethalBoykisserBase instance;

	public static Shader body;

	public Shader tail;

	internal ManualLogSource mls;

	public static ConfigEntry<bool> enabledForAllSuits { get; private set; }

	public static ConfigEntry<bool> playerScreams { get; private set; }

	public static ConfigEntry<string> suitsToEnable { get; private set; }

	private static string GetAssemblyName()
	{
		return Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];
	}

	private static void InitConfig()
	{
		enabledForAllSuits = config.Bind<bool>("Model Visability per Suit", "Enable for all", true, "Enable this to show the model for all suits");
		playerScreams = config.Bind<bool>("Screaming Expression", "Enable screaming", false, "Enable this to show another expression when your friends are screaming");
		suitsToEnable = config.Bind<string>("Suits to Replace Settings", "Suits to enable model replacement for", "Default,Orange suit", "Enter a comma separated list of suit names.(Additionally, [Green suit,Pajama suit,Hazard suit])");
	}

	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		if ((Object)instance == (Object)null)
		{
			instance = this;
		}
		config = ((BaseUnityPlugin)this).Config;
		InitConfig();
		if (enabledForAllSuits.Value)
		{
			ModelReplacementAPI.RegisterModelReplacementOverride(typeof(BodyReplacementBoy));
		}
		string[] array = suitsToEnable.Value.Split(new char[1] { ',' });
		string[] array2 = array;
		foreach (string text in array2)
		{
			ModelReplacementAPI.RegisterSuitModelReplacement(text, typeof(BodyReplacementBoy));
		}
		mls = Logger.CreateLogSource("LethallyGay.Boykisser");
		mls.LogInfo((object)"Loading the boykisser mod");
		Assets.PopulateAssets();
		harmony.PatchAll(typeof(LethalBoykisserBase));
		harmony.PatchAll(typeof(ExpressionManager));
		mls.LogInfo((object)"Boykisser mod loaded... (If you're reading this i just spent like 8+ hours rewriting this gg)");
	}
}

BepInEx/plugins/PushCompany/PushCompany.dll

Decompiled 8 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PushCompany.Assets.Scripts;
using PushCompany.Properties;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PushCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Push your fellow crewmates with the interaction key! (E by default)")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("PushCompany")]
[assembly: AssemblyTitle("PushCompany")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PushCompany
{
	[BepInPlugin("PushCompany", "PushCompany", "1.2.0")]
	public class PushCompanyBase : BaseUnityPlugin
	{
		public static readonly Lazy<PushCompanyBase> Instance = new Lazy<PushCompanyBase>(() => new PushCompanyBase());

		public static GameObject pushPrefab;

		public ManualLogSource mls;

		private readonly Harmony harmony = new Harmony("PushCompany");

		public static ConfigEntry<float> config_PushCooldown;

		public static ConfigEntry<float> config_PushForce;

		public static ConfigEntry<float> config_PushRange;

		public static ConfigEntry<float> config_PushCost;

		private void Awake()
		{
			mls = Logger.CreateLogSource("PushCompany");
			ConfigSetup();
			LoadBundle();
			harmony.PatchAll(typeof(PushCompanyBase));
			harmony.PatchAll(typeof(PlayerControllerB_Patches));
			harmony.PatchAll(typeof(NetworkHandler));
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			mls.LogInfo((object)"PushCompany has initialized!");
		}

		private void ConfigSetup()
		{
			config_PushCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Push Cooldown", "Value", 0.025f, "How long until the player can push again");
			config_PushForce = ((BaseUnityPlugin)this).Config.Bind<float>("Push Force", "Value", 12.5f, "How strong the player pushes.");
			config_PushRange = ((BaseUnityPlugin)this).Config.Bind<float>("Push Range", "Value", 3f, "The distance the player is able to push.");
			config_PushCost = ((BaseUnityPlugin)this).Config.Bind<float>("Push Cost", "Value", 0.08f, "The energy cost of each push.");
		}

		private void LoadBundle()
		{
			AssetBundle val = AssetBundle.LoadFromMemory(Resources.pushcompany);
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("Failed to load Push Bundle!");
			}
			pushPrefab = val.LoadAsset<GameObject>("Assets/Push.prefab");
			if ((Object)(object)pushPrefab == (Object)null)
			{
				throw new Exception("Failed to load Push Prefab!");
			}
			pushPrefab.AddComponent<PushComponent>();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PushCompany";

		public const string PLUGIN_NAME = "PushCompany";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace PushCompany.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("PushCompany.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] AssetBundles
		{
			get
			{
				object @object = ResourceManager.GetObject("AssetBundles", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] AssetBundles_manifest
		{
			get
			{
				object @object = ResourceManager.GetObject("AssetBundles.manifest", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] AssetBundles1
		{
			get
			{
				object @object = ResourceManager.GetObject("AssetBundles1", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] AssetBundles2
		{
			get
			{
				object @object = ResourceManager.GetObject("AssetBundles2", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] pushcompany
		{
			get
			{
				object @object = ResourceManager.GetObject("pushcompany", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] pushcompany_push
		{
			get
			{
				object @object = ResourceManager.GetObject("pushcompany.push", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] pushcompany_push_manifest
		{
			get
			{
				object @object = ResourceManager.GetObject("pushcompany.push.manifest", resourceCulture);
				return (byte[])@object;
			}
		}

		internal static byte[] pushcompany_push1
		{
			get
			{
				object @object = ResourceManager.GetObject("pushcompany.push1", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace PushCompany.Assets.Scripts
{
	[HarmonyPatch]
	public class NetworkHandler
	{
		private static GameObject pushObject;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		private static void Init()
		{
			NetworkManager.Singleton.AddNetworkPrefab(PushCompanyBase.pushPrefab);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkPrefab()
		{
			try
			{
				if (NetworkManager.Singleton.IsServer)
				{
					pushObject = Object.Instantiate<GameObject>(PushCompanyBase.pushPrefab);
					pushObject.GetComponent<NetworkObject>().Spawn(true);
				}
			}
			catch
			{
				PushCompanyBase.Instance.Value.mls.LogError((object)"Failed to instantiate network prefab!");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public static class PlayerControllerB_Patches
	{
		private static PushComponent pushComponent;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		private static void Update(PlayerControllerB __instance)
		{
			//IL_0016: 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)
			if (!((NetworkBehaviour)__instance).IsOwner)
			{
				return;
			}
			MovementActions movement = __instance.playerActions.Movement;
			if (((MovementActions)(ref movement)).Interact.WasPressedThisFrame())
			{
				if ((Object)(object)pushComponent == (Object)null)
				{
					pushComponent = Object.FindObjectOfType<PushComponent>();
				}
				if ((Object)(object)pushComponent != (Object)null)
				{
					pushComponent.PushServerRpc(((NetworkBehaviour)__instance).NetworkObjectId);
				}
			}
		}
	}
	public class PushComponent : NetworkBehaviour
	{
		private Dictionary<ulong, float> lastPushTimes = new Dictionary<ulong, float>();

		private NetworkVariable<float> PushCooldown = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private NetworkVariable<float> PushRange = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private NetworkVariable<float> PushForce = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private NetworkVariable<float> PushCost = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public override void OnNetworkSpawn()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				PushCooldown.Value = PushCompanyBase.config_PushCooldown.Value;
				PushRange.Value = PushCompanyBase.config_PushRange.Value;
				PushForce.Value = PushCompanyBase.config_PushForce.Value;
				PushCost.Value = PushCompanyBase.config_PushCost.Value;
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void PushServerRpc(ulong playerId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2433198804u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2433198804u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			if (lastPushTimes.TryGetValue(playerId, out var value))
			{
				if (Time.time - value < PushCooldown.Value)
				{
					return;
				}
			}
			else
			{
				lastPushTimes.Add(playerId, 0f);
			}
			GameObject playerById = GetPlayerById(playerId);
			PlayerControllerB component = playerById.GetComponent<PlayerControllerB>();
			Camera gameplayCamera = component.gameplayCamera;
			if (!CanPushPlayer(component))
			{
				return;
			}
			int num = 1 << playerById.layer;
			Vector3 forward = ((Component)gameplayCamera).transform.forward;
			Vector3 normalized = ((Vector3)(ref forward)).normalized;
			RaycastHit[] array = Physics.RaycastAll(((Component)gameplayCamera).transform.position, normalized, PushRange.Value, num);
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val3 = array2[i];
				if ((Object)(object)((Component)((RaycastHit)(ref val3)).transform).gameObject != (Object)(object)playerById)
				{
					PlayerControllerB component2 = ((Component)((RaycastHit)(ref val3)).transform).GetComponent<PlayerControllerB>();
					if (!component2.inSpecialInteractAnimation)
					{
						PushClientRpc(((NetworkBehaviour)component).NetworkObjectId, ((NetworkBehaviour)component2).NetworkObjectId, normalized * PushForce.Value * Time.fixedDeltaTime);
						lastPushTimes[playerId] = Time.time;
					}
					break;
				}
			}
		}

		[ClientRpc]
		private void PushClientRpc(ulong pusherId, ulong playerId, Vector3 push)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3498116674u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, pusherId);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref push);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3498116674u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					GameObject playerById = GetPlayerById(playerId);
					PlayerControllerB component = playerById.GetComponent<PlayerControllerB>();
					((MonoBehaviour)this).StartCoroutine(SmoothMove(component.thisController, push));
					component.movementAudio.PlayOneShot(StartOfRound.Instance.playerJumpSFX);
					GameObject playerById2 = GetPlayerById(pusherId);
					PlayerControllerB component2 = playerById2.GetComponent<PlayerControllerB>();
					component2.sprintMeter = Mathf.Clamp(component2.sprintMeter - PushCost.Value, 0f, 1f);
				}
			}
		}

		public IEnumerator SmoothMove(CharacterController controller, Vector3 push)
		{
			//IL_0015: 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)
			float force = PushForce.Value / 12.5f;
			float smoothTime = ((Vector3)(ref push)).magnitude / force;
			Vector3 targetPosition = ((Component)controller).transform.position + push;
			Vector3 val = targetPosition - ((Component)controller).transform.position;
			Vector3 direction = ((Vector3)(ref val)).normalized;
			float distance = Vector3.Distance(((Component)controller).transform.position, targetPosition);
			for (float currentTime = 0f; currentTime < smoothTime; currentTime += Time.fixedDeltaTime)
			{
				float currentDistance = distance * Mathf.Min(currentTime, smoothTime) / smoothTime;
				controller.Move(direction * currentDistance);
				yield return null;
			}
		}

		private bool CanPushPlayer(PlayerControllerB player)
		{
			return !player.quickMenuManager.isMenuOpen && !player.inSpecialInteractAnimation && !player.isTypingChat && !player.isExhausted;
		}

		private static GameObject GetPlayerById(ulong playerId)
		{
			if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value))
			{
				return ((Component)value).gameObject;
			}
			return null;
		}

		protected override void __initializeVariables()
		{
			if (PushCooldown == null)
			{
				throw new Exception("PushComponent.PushCooldown cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)PushCooldown).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)PushCooldown, "PushCooldown");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)PushCooldown);
			if (PushRange == null)
			{
				throw new Exception("PushComponent.PushRange cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)PushRange).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)PushRange, "PushRange");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)PushRange);
			if (PushForce == null)
			{
				throw new Exception("PushComponent.PushForce cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)PushForce).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)PushForce, "PushForce");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)PushForce);
			if (PushCost == null)
			{
				throw new Exception("PushComponent.PushCost cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)PushCost).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)PushCost, "PushCost");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)PushCost);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_PushComponent()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2433198804u, new RpcReceiveHandler(__rpc_handler_2433198804));
			NetworkManager.__rpc_func_table.Add(3498116674u, new RpcReceiveHandler(__rpc_handler_3498116674));
		}

		private static void __rpc_handler_2433198804(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong playerId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((PushComponent)(object)target).PushServerRpc(playerId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3498116674(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong pusherId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref pusherId);
				ulong playerId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				Vector3 push = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref push);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((PushComponent)(object)target).PushClientRpc(pusherId, playerId, push);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "PushComponent";
		}
	}
}

BepInEx/plugins/LethalConfig/LethalConfig.dll

Decompiled 8 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalConfig.Mods;
using LethalConfig.MonoBehaviours.Components;
using LethalConfig.Settings;
using LethalConfig.Utils;
using SharedUtils;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		MonoScriptData result = default(MonoScriptData);
		result.FilePathsData = new byte[3276]
		{
			0, 0, 0, 2, 0, 0, 0, 63, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 115, 92, 66, 97, 115, 101, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 71, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 92, 66, 111, 111, 108, 67,
			104, 101, 99, 107, 66, 111, 120, 67, 111, 110,
			102, 105, 103, 73, 116, 101, 109, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 71, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 115, 92, 69, 110, 117, 109, 68, 114,
			111, 112, 68, 111, 119, 110, 67, 111, 110, 102,
			105, 103, 73, 116, 101, 109, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 74, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 115, 92, 70, 108, 111, 97, 116, 73, 110,
			112, 117, 116, 70, 105, 101, 108, 100, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 70, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 92, 70, 108, 111, 97, 116,
			83, 108, 105, 100, 101, 114, 67, 111, 110, 102,
			105, 103, 73, 116, 101, 109, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 74, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 115, 92, 70, 108, 111, 97, 116, 83, 116,
			101, 112, 83, 108, 105, 100, 101, 114, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 72, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 92, 73, 110, 116, 73, 110,
			112, 117, 116, 70, 105, 101, 108, 100, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 68, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 92, 73, 110, 116, 83, 108,
			105, 100, 101, 114, 67, 111, 110, 102, 105, 103,
			73, 116, 101, 109, 46, 99, 115, 0, 0, 0,
			1, 0, 0, 0, 68, 92, 65, 115, 115, 101,
			116, 115, 92, 77, 111, 100, 115, 92, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			92, 83, 99, 114, 105, 112, 116, 115, 92, 67,
			111, 110, 102, 105, 103, 73, 116, 101, 109, 115,
			92, 79, 112, 116, 105, 111, 110, 115, 92, 66,
			97, 115, 101, 79, 112, 116, 105, 111, 110, 115,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			79, 92, 65, 115, 115, 101, 116, 115, 92, 77,
			111, 100, 115, 92, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 92, 83, 99, 114,
			105, 112, 116, 115, 92, 67, 111, 110, 102, 105,
			103, 73, 116, 101, 109, 115, 92, 79, 112, 116,
			105, 111, 110, 115, 92, 70, 108, 111, 97, 116,
			73, 110, 112, 117, 116, 70, 105, 101, 108, 100,
			79, 112, 116, 105, 111, 110, 115, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 75, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 115, 92, 79, 112, 116, 105, 111, 110,
			115, 92, 70, 108, 111, 97, 116, 83, 108, 105,
			100, 101, 114, 79, 112, 116, 105, 111, 110, 115,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			79, 92, 65, 115, 115, 101, 116, 115, 92, 77,
			111, 100, 115, 92, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 92, 83, 99, 114,
			105, 112, 116, 115, 92, 67, 111, 110, 102, 105,
			103, 73, 116, 101, 109, 115, 92, 79, 112, 116,
			105, 111, 110, 115, 92, 70, 108, 111, 97, 116,
			83, 116, 101, 112, 83, 108, 105, 100, 101, 114,
			79, 112, 116, 105, 111, 110, 115, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 77, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 115, 92, 79, 112, 116, 105, 111, 110,
			115, 92, 73, 110, 116, 73, 110, 112, 117, 116,
			70, 105, 101, 108, 100, 79, 112, 116, 105, 111,
			110, 115, 46, 99, 115, 0, 0, 0, 1, 0,
			0, 0, 73, 92, 65, 115, 115, 101, 116, 115,
			92, 77, 111, 100, 115, 92, 76, 101, 116, 104,
			97, 108, 67, 111, 110, 102, 105, 103, 92, 83,
			99, 114, 105, 112, 116, 115, 92, 67, 111, 110,
			102, 105, 103, 73, 116, 101, 109, 115, 92, 79,
			112, 116, 105, 111, 110, 115, 92, 73, 110, 116,
			83, 108, 105, 100, 101, 114, 79, 112, 116, 105,
			111, 110, 115, 46, 99, 115, 0, 0, 0, 1,
			0, 0, 0, 78, 92, 65, 115, 115, 101, 116,
			115, 92, 77, 111, 100, 115, 92, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 92,
			83, 99, 114, 105, 112, 116, 115, 92, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 115, 92,
			79, 112, 116, 105, 111, 110, 115, 92, 84, 101,
			120, 116, 73, 110, 112, 117, 116, 70, 105, 101,
			108, 100, 79, 112, 116, 105, 111, 110, 115, 46,
			99, 115, 0, 0, 0, 1, 0, 0, 0, 73,
			92, 65, 115, 115, 101, 116, 115, 92, 77, 111,
			100, 115, 92, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 67, 111, 110, 102, 105, 103,
			73, 116, 101, 109, 115, 92, 84, 101, 120, 116,
			73, 110, 112, 117, 116, 70, 105, 101, 108, 100,
			67, 111, 110, 102, 105, 103, 73, 116, 101, 109,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			56, 92, 65, 115, 115, 101, 116, 115, 92, 77,
			111, 100, 115, 92, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 92, 83, 99, 114,
			105, 112, 116, 115, 92, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 77, 97, 110,
			97, 103, 101, 114, 46, 99, 115, 0, 0, 0,
			2, 0, 0, 0, 55, 92, 65, 115, 115, 101,
			116, 115, 92, 77, 111, 100, 115, 92, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			92, 83, 99, 114, 105, 112, 116, 115, 92, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 80, 108, 117, 103, 105, 110, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 45, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 77, 111, 100, 115, 92, 77, 111, 100,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			49, 92, 65, 115, 115, 101, 116, 115, 92, 77,
			111, 100, 115, 92, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 92, 83, 99, 114,
			105, 112, 116, 115, 92, 77, 111, 100, 115, 92,
			77, 111, 100, 73, 110, 102, 111, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 85, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 77, 111, 110, 111, 66, 101, 104, 97,
			118, 105, 111, 117, 114, 115, 92, 67, 111, 109,
			112, 111, 110, 101, 110, 116, 115, 92, 66, 111,
			111, 108, 67, 104, 101, 99, 107, 66, 111, 120,
			67, 111, 110, 116, 114, 111, 108, 108, 101, 114,
			46, 99, 115, 0, 0, 0, 1, 0, 0, 0,
			85, 92, 65, 115, 115, 101, 116, 115, 92, 77,
			111, 100, 115, 92, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 92, 83, 99, 114,
			105, 112, 116, 115, 92, 77, 111, 110, 111, 66,
			101, 104, 97, 118, 105, 111, 117, 114, 115, 92,
			67, 111, 109, 112, 111, 110, 101, 110, 116, 115,
			92, 69, 110, 117, 109, 68, 114, 111, 112, 68,
			111, 119, 110, 67, 111, 110, 116, 114, 111, 108,
			108, 101, 114, 46, 99, 115, 0, 0, 0, 1,
			0, 0, 0, 88, 92, 65, 115, 115, 101, 116,
			115, 92, 77, 111, 100, 115, 92, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 92,
			83, 99, 114, 105, 112, 116, 115, 92, 77, 111,
			110, 111, 66, 101, 104, 97, 118, 105, 111, 117,
			114, 115, 92, 67, 111, 109, 112, 111, 110, 101,
			110, 116, 115, 92, 70, 108, 111, 97, 116, 73,
			110, 112, 117, 116, 70, 105, 101, 108, 100, 67,
			111, 110, 116, 114, 111, 108, 108, 101, 114, 46,
			99, 115, 0, 0, 0, 1, 0, 0, 0, 84,
			92, 65, 115, 115, 101, 116, 115, 92, 77, 111,
			100, 115, 92, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 77, 111, 110, 111, 66, 101,
			104, 97, 118, 105, 111, 117, 114, 115, 92, 67,
			111, 109, 112, 111, 110, 101, 110, 116, 115, 92,
			70, 108, 111, 97, 116, 83, 108, 105, 100, 101,
			114, 67, 111, 110, 116, 114, 111, 108, 108, 101,
			114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 88, 92, 65, 115, 115, 101, 116, 115, 92,
			77, 111, 100, 115, 92, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			92, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 92, 70, 108, 111, 97, 116, 83, 116, 101,
			112, 83, 108, 105, 100, 101, 114, 67, 111, 110,
			116, 114, 111, 108, 108, 101, 114, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 86, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 77, 111, 110, 111, 66, 101, 104, 97,
			118, 105, 111, 117, 114, 115, 92, 67, 111, 109,
			112, 111, 110, 101, 110, 116, 115, 92, 73, 110,
			116, 73, 110, 112, 117, 116, 70, 105, 101, 108,
			100, 67, 111, 110, 116, 114, 111, 108, 108, 101,
			114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 82, 92, 65, 115, 115, 101, 116, 115, 92,
			77, 111, 100, 115, 92, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			92, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 92, 73, 110, 116, 83, 108, 105, 100, 101,
			114, 67, 111, 110, 116, 114, 111, 108, 108, 101,
			114, 46, 99, 115, 0, 0, 0, 2, 0, 0,
			0, 82, 92, 65, 115, 115, 101, 116, 115, 92,
			77, 111, 100, 115, 92, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			92, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 92, 77, 111, 100, 67, 111, 110, 102, 105,
			103, 67, 111, 110, 116, 114, 111, 108, 108, 101,
			114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 87, 92, 65, 115, 115, 101, 116, 115, 92,
			77, 111, 100, 115, 92, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			92, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 92, 84, 101, 120, 116, 73, 110, 112, 117,
			116, 70, 105, 101, 108, 100, 67, 111, 110, 116,
			114, 111, 108, 108, 101, 114, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 62, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 77, 111, 110, 111, 66, 101, 104, 97, 118,
			105, 111, 117, 114, 115, 92, 67, 111, 110, 102,
			105, 103, 76, 105, 115, 116, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 62, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 77, 111, 110, 111, 66, 101, 104, 97, 118,
			105, 111, 117, 114, 115, 92, 67, 111, 110, 102,
			105, 103, 77, 101, 110, 117, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 69, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 77, 111, 110, 111, 66, 101, 104, 97, 118,
			105, 111, 117, 114, 115, 92, 67, 111, 110, 102,
			105, 103, 77, 101, 110, 117, 77, 97, 110, 97,
			103, 101, 114, 46, 99, 115, 0, 0, 0, 1,
			0, 0, 0, 66, 92, 65, 115, 115, 101, 116,
			115, 92, 77, 111, 100, 115, 92, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 92,
			83, 99, 114, 105, 112, 116, 115, 92, 77, 111,
			110, 111, 66, 101, 104, 97, 118, 105, 111, 117,
			114, 115, 92, 68, 101, 115, 99, 114, 105, 112,
			116, 105, 111, 110, 66, 111, 120, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 59, 92, 65,
			115, 115, 101, 116, 115, 92, 77, 111, 100, 115,
			92, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 77, 111, 110, 111, 66, 101, 104, 97,
			118, 105, 111, 117, 114, 115, 92, 77, 111, 100,
			76, 105, 115, 116, 46, 99, 115, 0, 0, 0,
			1, 0, 0, 0, 63, 92, 65, 115, 115, 101,
			116, 115, 92, 77, 111, 100, 115, 92, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			92, 83, 99, 114, 105, 112, 116, 115, 92, 77,
			111, 110, 111, 66, 101, 104, 97, 118, 105, 111,
			117, 114, 115, 92, 77, 111, 100, 76, 105, 115,
			116, 73, 116, 101, 109, 46, 99, 115, 0, 0,
			0, 1, 0, 0, 0, 65, 92, 65, 115, 115,
			101, 116, 115, 92, 77, 111, 100, 115, 92, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			77, 111, 110, 111, 66, 101, 104, 97, 118, 105,
			111, 117, 114, 115, 92, 83, 101, 99, 116, 105,
			111, 110, 72, 101, 97, 100, 101, 114, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 59, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 77, 111, 110, 111, 66, 101, 104,
			97, 118, 105, 111, 117, 114, 115, 92, 84, 111,
			111, 108, 116, 105, 112, 46, 99, 115, 0, 0,
			0, 1, 0, 0, 0, 65, 92, 65, 115, 115,
			101, 116, 115, 92, 77, 111, 100, 115, 92, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			77, 111, 110, 111, 66, 101, 104, 97, 118, 105,
			111, 117, 114, 115, 92, 84, 111, 111, 108, 116,
			105, 112, 83, 121, 115, 116, 101, 109, 46, 99,
			115, 0, 0, 0, 1, 0, 0, 0, 66, 92,
			65, 115, 115, 101, 116, 115, 92, 77, 111, 100,
			115, 92, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 92, 83, 99, 114, 105, 112,
			116, 115, 92, 77, 111, 110, 111, 66, 101, 104,
			97, 118, 105, 111, 117, 114, 115, 92, 84, 111,
			111, 108, 116, 105, 112, 84, 114, 105, 103, 103,
			101, 114, 46, 99, 115, 0, 0, 0, 1, 0,
			0, 0, 56, 92, 65, 115, 115, 101, 116, 115,
			92, 77, 111, 100, 115, 92, 76, 101, 116, 104,
			97, 108, 67, 111, 110, 102, 105, 103, 92, 83,
			99, 114, 105, 112, 116, 115, 92, 83, 101, 116,
			116, 105, 110, 103, 115, 92, 83, 101, 116, 116,
			105, 110, 103, 115, 85, 73, 46, 99, 115, 0,
			0, 0, 1, 0, 0, 0, 61, 92, 65, 115,
			115, 101, 116, 115, 92, 77, 111, 100, 115, 92,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 85, 116, 105, 108, 115, 92, 65, 115, 115,
			101, 109, 98, 108, 121, 69, 120, 116, 101, 110,
			115, 105, 111, 110, 115, 46, 99, 115, 0, 0,
			0, 1, 0, 0, 0, 50, 92, 65, 115, 115,
			101, 116, 115, 92, 77, 111, 100, 115, 92, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			85, 116, 105, 108, 115, 92, 80, 114, 101, 102,
			97, 98, 115, 46, 99, 115
		};
		result.TypesData = new byte[2242]
		{
			0, 0, 0, 0, 39, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 46, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 115, 124,
			66, 97, 115, 101, 67, 111, 110, 102, 105, 103,
			73, 116, 101, 109, 0, 0, 0, 0, 44, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 46, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 115, 124, 66, 97, 115, 101, 86, 97,
			108, 117, 101, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 0, 0, 0, 0, 47, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			46, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 115, 124, 66, 111, 111, 108, 67, 104, 101,
			99, 107, 66, 111, 120, 67, 111, 110, 102, 105,
			103, 73, 116, 101, 109, 0, 0, 0, 0, 47,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 46, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 124, 69, 110, 117, 109, 68,
			114, 111, 112, 68, 111, 119, 110, 67, 111, 110,
			102, 105, 103, 73, 116, 101, 109, 0, 0, 0,
			0, 50, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 46, 67, 111, 110, 102, 105,
			103, 73, 116, 101, 109, 115, 124, 70, 108, 111,
			97, 116, 73, 110, 112, 117, 116, 70, 105, 101,
			108, 100, 67, 111, 110, 102, 105, 103, 73, 116,
			101, 109, 0, 0, 0, 0, 46, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 46,
			67, 111, 110, 102, 105, 103, 73, 116, 101, 109,
			115, 124, 70, 108, 111, 97, 116, 83, 108, 105,
			100, 101, 114, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 0, 0, 0, 0, 50, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			46, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 115, 124, 70, 108, 111, 97, 116, 83, 116,
			101, 112, 83, 108, 105, 100, 101, 114, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 0, 0,
			0, 0, 48, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 46, 67, 111, 110, 102,
			105, 103, 73, 116, 101, 109, 115, 124, 73, 110,
			116, 73, 110, 112, 117, 116, 70, 105, 101, 108,
			100, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 0, 0, 0, 0, 44, 76, 101, 116, 104,
			97, 108, 67, 111, 110, 102, 105, 103, 46, 67,
			111, 110, 102, 105, 103, 73, 116, 101, 109, 115,
			124, 73, 110, 116, 83, 108, 105, 100, 101, 114,
			67, 111, 110, 102, 105, 103, 73, 116, 101, 109,
			0, 0, 0, 0, 44, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 46, 67, 111,
			110, 102, 105, 103, 73, 116, 101, 109, 115, 46,
			79, 112, 116, 105, 111, 110, 115, 124, 66, 97,
			115, 101, 79, 112, 116, 105, 111, 110, 115, 0,
			0, 0, 0, 55, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 67, 111, 110,
			102, 105, 103, 73, 116, 101, 109, 115, 46, 79,
			112, 116, 105, 111, 110, 115, 124, 70, 108, 111,
			97, 116, 73, 110, 112, 117, 116, 70, 105, 101,
			108, 100, 79, 112, 116, 105, 111, 110, 115, 0,
			0, 0, 0, 51, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 67, 111, 110,
			102, 105, 103, 73, 116, 101, 109, 115, 46, 79,
			112, 116, 105, 111, 110, 115, 124, 70, 108, 111,
			97, 116, 83, 108, 105, 100, 101, 114, 79, 112,
			116, 105, 111, 110, 115, 0, 0, 0, 0, 55,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 46, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 46, 79, 112, 116, 105, 111,
			110, 115, 124, 70, 108, 111, 97, 116, 83, 116,
			101, 112, 83, 108, 105, 100, 101, 114, 79, 112,
			116, 105, 111, 110, 115, 0, 0, 0, 0, 53,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 46, 67, 111, 110, 102, 105, 103, 73,
			116, 101, 109, 115, 46, 79, 112, 116, 105, 111,
			110, 115, 124, 73, 110, 116, 73, 110, 112, 117,
			116, 70, 105, 101, 108, 100, 79, 112, 116, 105,
			111, 110, 115, 0, 0, 0, 0, 49, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			46, 67, 111, 110, 102, 105, 103, 73, 116, 101,
			109, 115, 46, 79, 112, 116, 105, 111, 110, 115,
			124, 73, 110, 116, 83, 108, 105, 100, 101, 114,
			79, 112, 116, 105, 111, 110, 115, 0, 0, 0,
			0, 54, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 46, 67, 111, 110, 102, 105,
			103, 73, 116, 101, 109, 115, 46, 79, 112, 116,
			105, 111, 110, 115, 124, 84, 101, 120, 116, 73,
			110, 112, 117, 116, 70, 105, 101, 108, 100, 79,
			112, 116, 105, 111, 110, 115, 0, 0, 0, 0,
			49, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 46, 67, 111, 110, 102, 105, 103,
			73, 116, 101, 109, 115, 124, 84, 101, 120, 116,
			73, 110, 112, 117, 116, 70, 105, 101, 108, 100,
			67, 111, 110, 102, 105, 103, 73, 116, 101, 109,
			0, 0, 0, 0, 32, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 124, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			77, 97, 110, 97, 103, 101, 114, 0, 0, 0,
			0, 23, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 124, 80, 108, 117, 103, 105,
			110, 73, 110, 102, 111, 0, 0, 0, 0, 31,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 124, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 80, 108, 117, 103, 105,
			110, 0, 0, 0, 0, 21, 76, 101, 116, 104,
			97, 108, 67, 111, 110, 102, 105, 103, 46, 77,
			111, 100, 115, 124, 77, 111, 100, 0, 0, 0,
			0, 25, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 46, 77, 111, 100, 115, 124,
			77, 111, 100, 73, 110, 102, 111, 0, 0, 0,
			0, 61, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 46, 77, 111, 110, 111, 66,
			101, 104, 97, 118, 105, 111, 117, 114, 115, 46,
			67, 111, 109, 112, 111, 110, 101, 110, 116, 115,
			124, 66, 111, 111, 108, 67, 104, 101, 99, 107,
			66, 111, 120, 67, 111, 110, 116, 114, 111, 108,
			108, 101, 114, 0, 0, 0, 0, 61, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			46, 77, 111, 110, 111, 66, 101, 104, 97, 118,
			105, 111, 117, 114, 115, 46, 67, 111, 109, 112,
			111, 110, 101, 110, 116, 115, 124, 69, 110, 117,
			109, 68, 114, 111, 112, 68, 111, 119, 110, 67,
			111, 110, 116, 114, 111, 108, 108, 101, 114, 0,
			0, 0, 0, 64, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 77, 111, 110,
			111, 66, 101, 104, 97, 118, 105, 111, 117, 114,
			115, 46, 67, 111, 109, 112, 111, 110, 101, 110,
			116, 115, 124, 70, 108, 111, 97, 116, 73, 110,
			112, 117, 116, 70, 105, 101, 108, 100, 67, 111,
			110, 116, 114, 111, 108, 108, 101, 114, 0, 0,
			0, 0, 60, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 46, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			46, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 124, 70, 108, 111, 97, 116, 83, 108, 105,
			100, 101, 114, 67, 111, 110, 116, 114, 111, 108,
			108, 101, 114, 0, 0, 0, 0, 64, 76, 101,
			116, 104, 97, 108, 67, 111, 110, 102, 105, 103,
			46, 77, 111, 110, 111, 66, 101, 104, 97, 118,
			105, 111, 117, 114, 115, 46, 67, 111, 109, 112,
			111, 110, 101, 110, 116, 115, 124, 70, 108, 111,
			97, 116, 83, 116, 101, 112, 83, 108, 105, 100,
			101, 114, 67, 111, 110, 116, 114, 111, 108, 108,
			101, 114, 0, 0, 0, 0, 62, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 46,
			77, 111, 110, 111, 66, 101, 104, 97, 118, 105,
			111, 117, 114, 115, 46, 67, 111, 109, 112, 111,
			110, 101, 110, 116, 115, 124, 73, 110, 116, 73,
			110, 112, 117, 116, 70, 105, 101, 108, 100, 67,
			111, 110, 116, 114, 111, 108, 108, 101, 114, 0,
			0, 0, 0, 58, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 77, 111, 110,
			111, 66, 101, 104, 97, 118, 105, 111, 117, 114,
			115, 46, 67, 111, 109, 112, 111, 110, 101, 110,
			116, 115, 124, 73, 110, 116, 83, 108, 105, 100,
			101, 114, 67, 111, 110, 116, 114, 111, 108, 108,
			101, 114, 1, 0, 0, 0, 58, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 46,
			77, 111, 110, 111, 66, 101, 104, 97, 118, 105,
			111, 117, 114, 115, 46, 67, 111, 109, 112, 111,
			110, 101, 110, 116, 115, 124, 77, 111, 100, 67,
			111, 110, 102, 105, 103, 67, 111, 110, 116, 114,
			111, 108, 108, 101, 114, 1, 0, 0, 0, 58,
			76, 101, 116, 104, 97, 108, 67, 111, 110, 102,
			105, 103, 46, 77, 111, 110, 111, 66, 101, 104,
			97, 118, 105, 111, 117, 114, 115, 46, 67, 111,
			109, 112, 111, 110, 101, 110, 116, 115, 124, 77,
			111, 100, 67, 111, 110, 102, 105, 103, 67, 111,
			110, 116, 114, 111, 108, 108, 101, 114, 0, 0,
			0, 0, 63, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 46, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			46, 67, 111, 109, 112, 111, 110, 101, 110, 116,
			115, 124, 84, 101, 120, 116, 73, 110, 112, 117,
			116, 70, 105, 101, 108, 100, 67, 111, 110, 116,
			114, 111, 108, 108, 101, 114, 0, 0, 0, 0,
			38, 76, 101, 116, 104, 97, 108, 67, 111, 110,
			102, 105, 103, 46, 77, 111, 110, 111, 66, 101,
			104, 97, 118, 105, 111, 117, 114, 115, 124, 67,
			111, 110, 102, 105, 103, 76, 105, 115, 116, 0,
			0, 0, 0, 38, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 77, 111, 110,
			111, 66, 101, 104, 97, 118, 105, 111, 117, 114,
			115, 124, 67, 111, 110, 102, 105, 103, 77, 101,
			110, 117, 0, 0, 0, 0, 50, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 46,
			77, 111, 110, 111, 66, 101, 104, 97, 118, 105,
			111, 117, 114, 115, 124, 67, 111, 110, 102, 105,
			103, 77, 101, 110, 117, 65, 117, 100, 105, 111,
			77, 97, 110, 97, 103, 101, 114, 0, 0, 0,
			0, 42, 76, 101, 116, 104, 97, 108, 67, 111,
			110, 102, 105, 103, 46, 77, 111, 110, 111, 66,
			101, 104, 97, 118, 105, 111, 117, 114, 115, 124,
			68, 101, 115, 99, 114, 105, 112, 116, 105, 111,
			110, 66, 111, 120, 0, 0, 0, 0, 35, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 46, 77, 111, 110, 111, 66, 101, 104, 97,
			118, 105, 111, 117, 114, 115, 124, 77, 111, 100,
			76, 105, 115, 116, 0, 0, 0, 0, 39, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 46, 77, 111, 110, 111, 66, 101, 104, 97,
			118, 105, 111, 117, 114, 115, 124, 77, 111, 100,
			76, 105, 115, 116, 73, 116, 101, 109, 0, 0,
			0, 0, 41, 76, 101, 116, 104, 97, 108, 67,
			111, 110, 102, 105, 103, 46, 77, 111, 110, 111,
			66, 101, 104, 97, 118, 105, 111, 117, 114, 115,
			124, 83, 101, 99, 116, 105, 111, 110, 72, 101,
			97, 100, 101, 114, 0, 0, 0, 0, 20, 76,
			101, 116, 104, 97, 108, 67, 111, 110, 102, 105,
			103, 124, 84, 111, 111, 108, 116, 105, 112, 0,
			0, 0, 0, 26, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 124, 84, 111, 111,
			108, 116, 105, 112, 83, 121, 115, 116, 101, 109,
			0, 0, 0, 0, 27, 76, 101, 116, 104, 97,
			108, 67, 111, 110, 102, 105, 103, 124, 84, 111,
			111, 108, 116, 105, 112, 84, 114, 105, 103, 103,
			101, 114, 0, 0, 0, 0, 32, 76, 101, 116,
			104, 97, 108, 67, 111, 110, 102, 105, 103, 46,
			83, 101, 116, 116, 105, 110, 103, 115, 124, 83,
			101, 116, 116, 105, 110, 103, 115, 85, 73, 0,
			0, 0, 0, 37, 76, 101, 116, 104, 97, 108,
			67, 111, 110, 102, 105, 103, 46, 85, 116, 105,
			108, 115, 124, 65, 115, 115, 101, 109, 98, 108,
			121, 69, 120, 116, 101, 110, 115, 105, 111, 110,
			115, 0, 0, 0, 0, 26, 76, 101, 116, 104,
			97, 108, 67, 111, 110, 102, 105, 103, 46, 85,
			116, 105, 108, 115, 124, 80, 114, 101, 102, 97,
			98, 115
		};
		result.TotalFiles = 42;
		result.TotalTypes = 45;
		result.IsEditorOnly = false;
		return result;
	}
}
namespace LethalConfig
{
	public static class LethalConfigManager
	{
		internal static Dictionary<string, Mod> Mods { get; private set; } = new Dictionary<string, Mod>();


		public static void AddConfigItem(BaseConfigItem configItem)
		{
			Mod mod = ModForAssembly(Assembly.GetCallingAssembly());
			if (mod == null)
			{
				LogUtils.LogWarning("Mod for calling assembly not found.");
				return;
			}
			configItem.Owner = mod;
			mod.AddConfigItem(configItem);
			LogUtils.LogInfo($"Registered config \"{configItem}\"");
		}

		private static Mod ModForAssembly(Assembly assembly)
		{
			if (assembly.TryGetModInfo(out var modInfo))
			{
				if (Mods.TryGetValue(modInfo.GUID, out var value))
				{
					return value;
				}
				Mod mod = new Mod(modInfo);
				Mods.Add(modInfo.GUID, mod);
				return mod;
			}
			return null;
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "ainavt.lc.lethalconfig";

		public const string Name = "LethalConfig";

		public const string Version = "1.0.1";
	}
	[BepInPlugin("ainavt.lc.lethalconfig", "LethalConfig", "1.0.1")]
	internal class LethalConfigPlugin : BaseUnityPlugin
	{
		private enum TestEnum
		{
			None,
			First,
			Second
		}

		private static LethalConfigPlugin instance;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			LogUtils.Init("ainavt.lc.lethalconfig");
			Prefabs.Init();
			SettingsUI.Init();
			CreateExampleConfigs();
			LogUtils.LogInfo("LethalConfig loaded!");
		}

		private void CreateExampleConfigs()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			ConfigEntry<int> configEntry = ((BaseUnityPlugin)this).Config.Bind<int>("Example", "Int Slider", 30, new ConfigDescription("This is an integer slider. You can also type a value in the input field to the right of the slider.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			ConfigEntry<float> configEntry2 = ((BaseUnityPlugin)this).Config.Bind<float>("Example", "Float Slider", 0f, new ConfigDescription("This is a float slider. You can also type a value in the input field to the right of the slider.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), Array.Empty<object>()));
			ConfigEntry<float> configEntry3 = ((BaseUnityPlugin)this).Config.Bind<float>("Example", "Float Step Slider", 0f, new ConfigDescription("This is a float step slider. It set values in increments. You can also type a value in the input field to the right of the slider.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), Array.Empty<object>()));
			ConfigEntry<bool> configEntry4 = ((BaseUnityPlugin)this).Config.Bind<bool>("Example", "Bool Checkbox", false, new ConfigDescription("This is a bool checkbox.", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<TestEnum> configEntry5 = ((BaseUnityPlugin)this).Config.Bind<TestEnum>("Example", "Enum Dropdown", TestEnum.None, new ConfigDescription("This is a enum dropdown.", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigEntry<string> configEntry6 = ((BaseUnityPlugin)this).Config.Bind<string>("Example", "Text Input", "Example", "This is a text input field. It can have a limit of characters too.");
			ConfigEntry<int> configEntry7 = ((BaseUnityPlugin)this).Config.Bind<int>("Example", "Int Input", 50, "This is an integer input field.");
			ConfigEntry<float> configEntry8 = ((BaseUnityPlugin)this).Config.Bind<float>("Example", "Float Input", 0.5f, "This is a float input field.");
			LethalConfigManager.AddConfigItem(new IntSliderConfigItem(configEntry, requiresRestart: false));
			LethalConfigManager.AddConfigItem(new FloatSliderConfigItem(configEntry2, requiresRestart: false));
			LethalConfigManager.AddConfigItem(new FloatStepSliderConfigItem(configEntry3, new FloatStepSliderOptions
			{
				Step = 0.1f,
				RequiresRestart = false,
				Min = -1f,
				Max = 1f
			}));
			LethalConfigManager.AddConfigItem(new BoolCheckBoxConfigItem(configEntry4, requiresRestart: false));
			LethalConfigManager.AddConfigItem(new EnumDropDownConfigItem<TestEnum>(configEntry5, requiresRestart: false));
			LethalConfigManager.AddConfigItem(new TextInputFieldConfigItem(configEntry6, requiresRestart: false));
			LethalConfigManager.AddConfigItem(new IntInputFieldConfigItem(configEntry7, new IntInputFieldOptions
			{
				Max = 150
			}));
			LethalConfigManager.AddConfigItem(new FloatInputFieldConfigItem(configEntry8, new FloatInputFieldOptions
			{
				Max = 2.5f
			}));
		}
	}
	internal class Tooltip : MonoBehaviour
	{
		public TextMeshProUGUI textComponent;

		private RectTransform rectTransform;

		private Camera uiCamera;

		public void SetText(string text)
		{
			((TMP_Text)textComponent).text = text;
		}

		private void Awake()
		{
			ref RectTransform reference = ref rectTransform;
			Transform transform = ((Component)this).transform;
			reference = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			uiCamera = GameObject.Find("UICamera").GetComponent<Camera>();
		}

		private void LateUpdate()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0036: 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)
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			Transform parent = ((Component)this).transform.parent;
			Vector2 val2 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), val, uiCamera, ref val2))
			{
				((Transform)rectTransform).localPosition = Vector2.op_Implicit(val2);
			}
		}
	}
	internal class TooltipSystem : MonoBehaviour
	{
		private static TooltipSystem instance;

		public Tooltip tooltip;

		private void Awake()
		{
			instance = this;
		}

		public static void Show(string content)
		{
			if (!((Object)(object)instance == (Object)null))
			{
				((Component)instance.tooltip).gameObject.SetActive(true);
				instance.tooltip.SetText(content);
			}
		}

		public static void Hide()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				((Component)instance.tooltip).gameObject.SetActive(false);
			}
		}
	}
	internal class TooltipTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public string tooltipText;

		public void OnPointerEnter(PointerEventData eventData)
		{
			TooltipSystem.Show(tooltipText);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			TooltipSystem.Hide();
		}
	}
}
namespace LethalConfig.Utils
{
	internal static class AssemblyExtensions
	{
		internal static bool TryGetModInfo(this Assembly assembly, out ModInfo modInfo)
		{
			modInfo = default(ModInfo);
			Type[] types = assembly.GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				BepInPlugin customAttribute = ((MemberInfo)types[i]).GetCustomAttribute<BepInPlugin>();
				if (customAttribute != null)
				{
					modInfo.Name = customAttribute.Name;
					modInfo.GUID = customAttribute.GUID;
					modInfo.Version = customAttribute.Version.ToString();
					return true;
				}
			}
			return false;
		}
	}
	internal static class Prefabs
	{
		private static AssetBundle assetBundle;

		internal static GameObject ConfigMenuPrefab;

		internal static GameObject ModListItemPrefab;

		internal static GameObject SectionHeaderPrefab;

		internal static GameObject IntSliderPrefab;

		internal static GameObject FloatSliderPrefab;

		internal static GameObject FloatStepSliderPrefab;

		internal static GameObject BoolCheckBoxPrefab;

		internal static GameObject EnumDropDownPrefab;

		internal static GameObject TextInputFieldPrefab;

		internal static GameObject IntInputFieldPrefab;

		internal static GameObject FloatInputFieldPrefab;

		internal static void Init()
		{
			assetBundle = AssetBundle.LoadFromFile(PathUtils.PathForResourceInAssembly("ainavt_lethalconfig", (Assembly)null));
			if ((Object)(object)assetBundle == (Object)null)
			{
				LogUtils.LogError("Failed to load LethalConfig bundle.");
				return;
			}
			LoadPrefab("ConfigMenu.prefab", out ConfigMenuPrefab);
			LoadPrefab("ModListItem.prefab", out ModListItemPrefab);
			LoadPrefab("SectionHeader.prefab", out SectionHeaderPrefab);
			LoadPrefab("IntSliderItem.prefab", out IntSliderPrefab);
			LoadPrefab("FloatSliderItem.prefab", out FloatSliderPrefab);
			LoadPrefab("FloatStepSliderItem.prefab", out FloatStepSliderPrefab);
			LoadPrefab("BoolCheckBoxItem.prefab", out BoolCheckBoxPrefab);
			LoadPrefab("EnumDropDownItem.prefab", out EnumDropDownPrefab);
			LoadPrefab("TextInputFieldItem.prefab", out TextInputFieldPrefab);
			LoadPrefab("IntInputFieldItem.prefab", out IntInputFieldPrefab);
			LoadPrefab("FloatInputFieldItem.prefab", out FloatInputFieldPrefab);
			LogUtils.LogInfo("Finished loading prefabs.");
		}

		private static void LoadPrefab(string prefabName, out GameObject prefab)
		{
			string text = "Assets/mods/lethalconfig/prefabs/" + prefabName;
			prefab = assetBundle.LoadAsset<GameObject>(text);
			if ((Object)(object)prefab == (Object)null)
			{
				LogUtils.LogError("Failed to load prefab (" + text + ")");
			}
		}
	}
}
namespace LethalConfig.Settings
{
	internal static class SettingsUI
	{
		private static bool hasInitialized;

		internal static void Init()
		{
			if (!hasInitialized)
			{
				SceneManager.sceneLoaded += OnSceneLoaded;
				hasInitialized = true;
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_01f7: 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_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Scene)(ref scene)).name == "MainMenu"))
			{
				return;
			}
			LogUtils.LogInfo("Injecting mod config menu into main menu...");
			MenuManager menuManager = GameObject.Find("MenuManager").GetComponent<MenuManager>();
			GameObject val = GameObject.Find("MenuContainer");
			GameObject gameObject = ((Component)val.transform.Find("MainButtons")).gameObject;
			GameObject gameObject2 = ((Component)gameObject.transform.Find("Credits")).gameObject;
			GameObject gameObject3 = ((Component)val.transform.Find("MenuNotification")).gameObject;
			GameObject configMenu = Object.Instantiate<GameObject>(Prefabs.ConfigMenuPrefab);
			configMenu.transform.SetParent(val.transform, false);
			configMenu.transform.localPosition = Vector3.zero;
			configMenu.transform.localScale = Vector3.one;
			configMenu.transform.localRotation = Quaternion.identity;
			configMenu.transform.SetSiblingIndex(gameObject3.transform.GetSiblingIndex());
			configMenu.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(gameObject2, gameObject.transform);
			((UnityEventBase)val2.GetComponent<Button>().onClick).RemoveAllListeners();
			val2.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				menuManager.EnableUIPanel(configMenu);
			});
			((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				menuManager.PlayConfirmSFX();
			});
			((TMP_Text)val2.GetComponentInChildren<TextMeshProUGUI>()).text = "> LethalConfig";
			IEnumerable<GameObject> source = from b in gameObject.GetComponentsInChildren<Button>(true)
				select ((Component)b).gameObject;
			foreach (GameObject item in source.Where((GameObject g) => ((Object)g).name != "QuitButton" && ((Object)g).name != "Credits"))
			{
				RectTransform component = item.GetComponent<RectTransform>();
				component.anchoredPosition += new Vector2(0f, 38.5f);
			}
			val2.GetComponent<RectTransform>().anchoredPosition = source.First((GameObject g) => ((Object)g).name == "Credits").GetComponent<RectTransform>().anchoredPosition + new Vector2(0f, 38.5f);
		}
	}
}
namespace LethalConfig.MonoBehaviours
{
	internal class ConfigList : MonoBehaviour
	{
		public GameObject listContainerObject;

		public DescriptionBox descriptionBox;

		public ConfigMenuAudioManager audioManager;

		internal void LoadConfigsForMod(Mod mod)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			ClearConfigList();
			foreach (IGrouping<string, BaseConfigItem> item in from c in mod.configItems
				group c by c.Section)
			{
				GameObject obj = Object.Instantiate<GameObject>(Prefabs.SectionHeaderPrefab);
				obj.GetComponent<SectionHeader>().SetSectionName(item.Key);
				obj.transform.SetParent(listContainerObject.transform);
				obj.transform.localPosition = Vector3.zero;
				obj.transform.localScale = Vector3.one;
				obj.transform.localRotation = Quaternion.identity;
				foreach (BaseConfigItem item2 in item)
				{
					GameObject val = item2.CreateGameObjectForConfig();
					ModConfigController controller = val.GetComponent<ModConfigController>();
					if (!controller.SetConfigItem(item2))
					{
						Object.DestroyImmediate((Object)(object)val.gameObject);
						return;
					}
					val.transform.SetParent(listContainerObject.transform);
					val.transform.localPosition = Vector3.zero;
					val.transform.localScale = Vector3.one;
					val.transform.localRotation = Quaternion.identity;
					controller.OnHoverEnter += delegate
					{
						descriptionBox.SetDescription(controller.GetDescription());
					};
					controller.OnHoverExit += delegate
					{
						descriptionBox.SetDescription("");
					};
					controller.audioManager = audioManager;
				}
			}
		}

		private void ClearConfigList()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			foreach (Transform item in listContainerObject.transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}
	}
	internal class ConfigMenu : MonoBehaviour
	{
		public ConfigList configList;

		public DescriptionBox descriptionBox;

		public ConfigMenuAudioManager audioManager;

		private MenuManager menuManager;

		public void OnCancelButtonClicked()
		{
			if (!EnsureMenuManagerInstance())
			{
				return;
			}
			foreach (BaseConfigItem item in LethalConfigManager.Mods.SelectMany((KeyValuePair<string, Mod> m) => m.Value.configItems))
			{
				item.CancelChanges();
			}
			UpdateAppearanceOfCurrentComponents();
			menuManager.DisableUIPanel(((Component)this).gameObject);
			menuManager.PlayCancelSFX();
		}

		public void OnApplyButtonClicked()
		{
			if (!EnsureMenuManagerInstance())
			{
				return;
			}
			List<BaseConfigItem> list = (from c in LethalConfigManager.Mods.SelectMany((KeyValuePair<string, Mod> m) => m.Value.configItems)
				where c.HasValueChanged
				select c).ToList();
			List<BaseConfigItem> list2 = list.Where((BaseConfigItem c) => c.RequiresRestart).ToList();
			foreach (BaseConfigItem item in list)
			{
				item.ApplyChanges();
			}
			UpdateAppearanceOfCurrentComponents();
			menuManager.PlayConfirmSFX();
			LogUtils.LogInfo($"Saved config values for {list.Count} items.");
			LogUtils.LogInfo($"Modified {list2.Count} item(s) that requires a restart.");
			if (list2.Count > 0)
			{
				menuManager.DisplayMenuNotification("Some of the modified settings will only take effect after restarting the game.", "[OK]");
			}
		}

		public void ShowItemDescription(string description)
		{
			descriptionBox.SetDescription(description);
		}

		private bool EnsureMenuManagerInstance()
		{
			if ((Object)(object)menuManager == (Object)null)
			{
				GameObject val = GameObject.Find("MenuManager");
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				menuManager = val.GetComponent<MenuManager>();
				if ((Object)(object)menuManager == (Object)null)
				{
					return false;
				}
			}
			return true;
		}

		private void UpdateAppearanceOfCurrentComponents()
		{
			ModConfigController[] componentsInChildren = ((Component)configList).GetComponentsInChildren<ModConfigController>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].UpdateAppearance();
			}
		}
	}
	internal class ConfigMenuAudioManager : MonoBehaviour
	{
		public AudioClip confirmSFX;

		public AudioClip cancelSFX;

		public AudioClip selectSFX;

		public AudioClip hoverSFX;

		public AudioClip changeValueSFX;

		private MenuManager menuManager;

		private void Awake()
		{
			menuManager = GameObject.Find("MenuManager").GetComponent<MenuManager>();
		}

		public void PlayConfirmSFX()
		{
			menuManager.MenuAudio.PlayOneShot(confirmSFX);
		}

		public void PlayCancelSFX()
		{
			menuManager.MenuAudio.PlayOneShot(cancelSFX);
		}

		public void PlayHoverSFX()
		{
			menuManager.MenuAudio.PlayOneShot(hoverSFX);
		}

		public void PlaySelectSFX()
		{
			menuManager.MenuAudio.PlayOneShot(selectSFX);
		}

		public void PlayChangeValueSFX()
		{
			menuManager.MenuAudio.PlayOneShot(changeValueSFX);
		}
	}
	internal class DescriptionBox : MonoBehaviour
	{
		public TextMeshProUGUI textMesh;

		public void SetDescription(string description)
		{
			((TMP_Text)textMesh).text = description;
		}
	}
	internal class ModList : MonoBehaviour
	{
		public GameObject modItemPrefab;

		public GameObject listContainerObject;

		public ConfigList configList;

		public DescriptionBox descriptionBox;

		public ConfigMenuAudioManager audioManager;

		private List<ModListItem> _items;

		private void Awake()
		{
			_items = new List<ModListItem>();
			audioManager = GameObject.Find("ConfigMenuAudioManager").GetComponent<ConfigMenuAudioManager>();
			BuildModList();
		}

		private void BuildModList()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			_items.Clear();
			foreach (Transform item in listContainerObject.transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (Mod value in LethalConfigManager.Mods.Values)
			{
				GameObject val = Object.Instantiate<GameObject>(modItemPrefab, listContainerObject.transform);
				val.transform.localScale = Vector3.one;
				val.transform.localPosition = Vector3.zero;
				val.transform.localRotation = Quaternion.identity;
				ModListItem listItem = val.GetComponent<ModListItem>();
				listItem.mod = value;
				listItem.modSelected += ModSelected;
				listItem.audioManager = audioManager;
				listItem.OnHoverEnter += delegate
				{
					descriptionBox.SetDescription(listItem.GetDescription());
				};
				listItem.OnHoverExit += delegate
				{
					descriptionBox.SetDescription("");
				};
				_items.Add(val.GetComponent<ModListItem>());
			}
		}

		private void ModSelected(Mod mod)
		{
			audioManager.PlayConfirmSFX();
			configList.LoadConfigsForMod(mod);
			_items.First((ModListItem i) => i.mod == mod).SetSelected(selected: true);
			foreach (ModListItem item in _items.Where((ModListItem i) => i.mod != mod))
			{
				item.SetSelected(selected: false);
			}
		}
	}
	internal class ModListItem : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public delegate void OnHoverHandler();

		internal delegate void ModSelectedHandler(Mod mod);

		public TextMeshProUGUI textMesh;

		public GameObject selectedBorder;

		internal ConfigMenuAudioManager audioManager;

		private Mod _mod;

		internal Mod mod
		{
			get
			{
				return _mod;
			}
			set
			{
				_mod = value;
				((TMP_Text)textMesh).text = _mod.modInfo.Name;
			}
		}

		public event OnHoverHandler OnHoverEnter;

		public event OnHoverHandler OnHoverExit;

		internal event ModSelectedHandler modSelected;

		public void OnClick()
		{
			this.modSelected(_mod);
		}

		public void SetSelected(bool selected)
		{
			selectedBorder.SetActive(selected);
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			this.OnHoverEnter();
			audioManager.PlayHoverSFX();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			this.OnHoverExit();
		}

		public string GetDescription()
		{
			return _mod.modInfo.Name + "\n" + _mod.modInfo.GUID + "\n" + _mod.modInfo.Version;
		}
	}
	internal class SectionHeader : MonoBehaviour
	{
		public TextMeshProUGUI textMesh;

		public void SetSectionName(string sectionName)
		{
			((TMP_Text)textMesh).text = "[" + sectionName + "]";
		}
	}
}
namespace LethalConfig.MonoBehaviours.Components
{
	internal class BoolCheckBoxController : ModConfigController<BoolCheckBoxConfigItem, bool>
	{
		public Toggle toggleComponent;

		public TextMeshProUGUI nameTextComponent;

		public override void UpdateAppearance()
		{
			toggleComponent.SetIsOnWithoutNotify(base.ConfigItem.CurrentValue);
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
		}

		protected override void OnSetConfigItem()
		{
			toggleComponent.SetIsOnWithoutNotify(base.ConfigItem.CurrentValue);
			UpdateAppearance();
		}

		public void OnCheckBoxValueChanged(bool value)
		{
			base.ConfigItem.CurrentValue = value;
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public void OnPointerClicked(BaseEventData eventData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = (PointerEventData)(object)((eventData is PointerEventData) ? eventData : null);
			if (val != null && (int)val.button == 0)
			{
				toggleComponent.isOn = !toggleComponent.isOn;
			}
		}
	}
	internal class EnumDropDownController : ModConfigController
	{
		public TMP_Dropdown dropdownComponent;

		public TextMeshProUGUI nameTextComponent;

		private Type _enumType;

		private List<string> _enumNames = new List<string>();

		public override string GetDescription()
		{
			return base.GetDescription() + "\n\nDefault: " + Enum.GetName(_enumType, baseConfigItem.BoxedDefaultValue);
		}

		public override void UpdateAppearance()
		{
			((TMP_Text)nameTextComponent).text = (baseConfigItem.HasValueChanged ? "*" : "") + baseConfigItem.Name;
			int valueWithoutNotify = _enumNames.FindIndex((string e) => e == Enum.GetName(_enumType, baseConfigItem.CurrentBoxedValue));
			dropdownComponent.SetValueWithoutNotify(valueWithoutNotify);
		}

		protected override void OnSetConfigItem()
		{
			_enumType = baseConfigItem.BaseConfigEntry.SettingType;
			_enumNames = Enum.GetNames(_enumType).ToList();
			dropdownComponent.ClearOptions();
			dropdownComponent.AddOptions(_enumNames);
			int valueWithoutNotify = _enumNames.FindIndex((string e) => e == Enum.GetName(_enumType, baseConfigItem.CurrentBoxedValue));
			dropdownComponent.SetValueWithoutNotify(valueWithoutNotify);
			UpdateAppearance();
		}

		public void OnDropDownValueChanged(int index)
		{
			baseConfigItem.CurrentBoxedValue = Enum.Parse(_enumType, _enumNames[index]);
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}
	}
	internal class FloatInputFieldController : ModConfigController<FloatInputFieldConfigItem, float>
	{
		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField textInputField;

		public override string GetDescription()
		{
			string text = base.GetDescription();
			if (base.ConfigItem.MinValue != float.MinValue)
			{
				text += $"\nMin: {base.ConfigItem.MinValue:0.0#}";
			}
			if (base.ConfigItem.MaxValue != float.MaxValue)
			{
				text += $"\nMax: {base.ConfigItem.MaxValue:0.0#}";
			}
			return text;
		}

		protected override void OnSetConfigItem()
		{
			textInputField.text = $"{base.ConfigItem.CurrentValue}";
			UpdateAppearance();
		}

		public void OnInputFieldEndEdit(string value)
		{
			if (float.TryParse(value, out var result))
			{
				base.ConfigItem.CurrentValue = Math.Clamp(result, base.ConfigItem.MinValue, base.ConfigItem.MaxValue);
			}
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			textInputField.SetTextWithoutNotify($"{base.ConfigItem.CurrentValue}");
			((Transform)textInputField.textComponent.rectTransform).localPosition = Vector3.zero;
		}
	}
	internal class FloatSliderController : ModConfigController<FloatSliderConfigItem, float>
	{
		public Slider sliderComponent;

		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField valueInputField;

		public override string GetDescription()
		{
			return $"{base.GetDescription()}\nMin: {base.ConfigItem.MinValue:0.0#}\nMax: {base.ConfigItem.MaxValue:0.0#}";
		}

		protected override void OnSetConfigItem()
		{
			sliderComponent.maxValue = base.ConfigItem.MaxValue;
			sliderComponent.minValue = base.ConfigItem.MinValue;
			sliderComponent.SetValueWithoutNotify(base.ConfigItem.CurrentValue);
			UpdateAppearance();
		}

		public void OnSliderValueChanged(float value)
		{
			base.ConfigItem.CurrentValue = value;
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public void OnInputFieldEndEdit(string value)
		{
			if (float.TryParse(value, out var result))
			{
				base.ConfigItem.CurrentValue = Math.Clamp(result, base.ConfigItem.MinValue, base.ConfigItem.MaxValue);
			}
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			sliderComponent.SetValueWithoutNotify(base.ConfigItem.CurrentValue);
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			valueInputField.SetTextWithoutNotify($"{base.ConfigItem.CurrentValue:0.0#}");
		}
	}
	internal class FloatStepSliderController : ModConfigController<FloatStepSliderConfigItem, float>
	{
		public Slider sliderComponent;

		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField valueInputField;

		public override string GetDescription()
		{
			return $"{base.GetDescription()}\nMin: {base.ConfigItem.MinValue:0.0#}\nMax: {base.ConfigItem.MaxValue:0.0#}";
		}

		protected override void OnSetConfigItem()
		{
			int num = (int)MathF.Ceiling((base.ConfigItem.MaxValue - base.ConfigItem.MinValue) / MathF.Max(base.ConfigItem.Step, float.Epsilon));
			sliderComponent.maxValue = num;
			sliderComponent.minValue = 0f;
			sliderComponent.wholeNumbers = true;
			sliderComponent.SetValueWithoutNotify(base.ConfigItem.CurrentValue);
			UpdateAppearance();
		}

		public void OnSliderValueChanged(float value)
		{
			base.ConfigItem.CurrentValue = MathF.Round(base.ConfigItem.MinValue + base.ConfigItem.Step * (float)(int)value, 4);
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public void OnInputFieldEndEdit(string value)
		{
			if (float.TryParse(value, out var result))
			{
				base.ConfigItem.CurrentValue = Math.Clamp(result, base.ConfigItem.MinValue, base.ConfigItem.MaxValue);
			}
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			sliderComponent.SetValueWithoutNotify((base.ConfigItem.CurrentValue - base.ConfigItem.MinValue) / MathF.Max(base.ConfigItem.Step, float.Epsilon));
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			valueInputField.SetTextWithoutNotify($"{base.ConfigItem.CurrentValue:0.0#}");
		}
	}
	internal class IntInputFieldController : ModConfigController<IntInputFieldConfigItem, int>
	{
		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField textInputField;

		public override string GetDescription()
		{
			string text = base.GetDescription();
			if (base.ConfigItem.MinValue != int.MinValue)
			{
				text += $"\nMin: {base.ConfigItem.MinValue}";
			}
			if (base.ConfigItem.MaxValue != int.MaxValue)
			{
				text += $"\nMax: {base.ConfigItem.MaxValue}";
			}
			return text;
		}

		protected override void OnSetConfigItem()
		{
			textInputField.text = $"{base.ConfigItem.CurrentValue}";
			UpdateAppearance();
		}

		public void OnInputFieldEndEdit(string value)
		{
			if (int.TryParse(value, out var result))
			{
				base.ConfigItem.CurrentValue = Math.Clamp(result, base.ConfigItem.MinValue, base.ConfigItem.MaxValue);
			}
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			textInputField.SetTextWithoutNotify($"{base.ConfigItem.CurrentValue}");
			((Transform)textInputField.textComponent.rectTransform).localPosition = Vector3.zero;
		}
	}
	internal class IntSliderController : ModConfigController<IntSliderConfigItem, int>
	{
		public Slider sliderComponent;

		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField valueInputField;

		public override string GetDescription()
		{
			return $"{base.GetDescription()}\nMin: {base.ConfigItem.MinValue}\nMax: {base.ConfigItem.MaxValue}";
		}

		protected override void OnSetConfigItem()
		{
			sliderComponent.maxValue = base.ConfigItem.MaxValue;
			sliderComponent.minValue = base.ConfigItem.MinValue;
			sliderComponent.SetValueWithoutNotify((float)base.ConfigItem.CurrentValue);
			UpdateAppearance();
		}

		public void OnSliderValueChanged(float value)
		{
			base.ConfigItem.CurrentValue = (int)value;
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public void OnInputFieldEndEdit(string value)
		{
			if (int.TryParse(value, out var result))
			{
				base.ConfigItem.CurrentValue = Math.Clamp(result, base.ConfigItem.MinValue, base.ConfigItem.MaxValue);
			}
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			sliderComponent.SetValueWithoutNotify((float)base.ConfigItem.CurrentValue);
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			valueInputField.SetTextWithoutNotify($"{base.ConfigItem.CurrentValue}");
		}
	}
	internal abstract class ModConfigController : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public delegate void OnHoverHandler();

		protected BaseConfigItem baseConfigItem;

		internal ConfigMenuAudioManager audioManager;

		public event OnHoverHandler OnHoverEnter;

		public event OnHoverHandler OnHoverExit;

		public virtual bool SetConfigItem(BaseConfigItem configItem)
		{
			baseConfigItem = configItem;
			OnSetConfigItem();
			return true;
		}

		protected abstract void OnSetConfigItem();

		public abstract void UpdateAppearance();

		public virtual void ResetToDefault()
		{
			audioManager.PlayConfirmSFX();
			baseConfigItem.ChangeToDefault();
			UpdateAppearance();
		}

		public virtual string GetDescription()
		{
			if (baseConfigItem.RequiresRestart)
			{
				return baseConfigItem.Name + "\n*REQUIRES RESTART*\n\n" + baseConfigItem.Description;
			}
			return baseConfigItem.Name + "\n\n" + baseConfigItem.Description;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			this.OnHoverEnter();
			audioManager.PlayHoverSFX();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			this.OnHoverExit();
		}
	}
	internal abstract class ModConfigController<T, V> : ModConfigController where T : BaseValueConfigItem<V>
	{
		public T ConfigItem => (T)baseConfigItem;

		public override string GetDescription()
		{
			return $"{base.GetDescription()}\n\nDefault: {ConfigItem.Defaultvalue}";
		}

		public override bool SetConfigItem(BaseConfigItem configItem)
		{
			if (!(configItem is T))
			{
				LogUtils.LogError("Expected config item of type " + typeof(T).Name + ", but got " + configItem.GetType().Name + " instead.");
				return false;
			}
			return base.SetConfigItem(configItem);
		}
	}
	internal class TextInputFieldController : ModConfigController<TextInputFieldConfigItem, string>
	{
		public TextMeshProUGUI nameTextComponent;

		public TMP_InputField textInputField;

		protected override void OnSetConfigItem()
		{
			textInputField.text = base.ConfigItem.CurrentValue;
			UpdateAppearance();
		}

		public void OnInputFieldEndEdit(string value)
		{
			base.ConfigItem.CurrentValue = value;
			UpdateAppearance();
			audioManager.PlayChangeValueSFX();
		}

		public override void UpdateAppearance()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)nameTextComponent).text = (base.ConfigItem.HasValueChanged ? "*" : "") + base.ConfigItem.Name;
			textInputField.SetTextWithoutNotify(base.ConfigItem.CurrentValue);
			((Transform)textInputField.textComponent.rectTransform).localPosition = Vector3.zero;
		}
	}
}
namespace LethalConfig.Mods
{
	internal class Mod
	{
		public ModInfo modInfo;

		public List<BaseConfigItem> configItems;

		internal Mod(ModInfo modInfo)
		{
			configItems = new List<BaseConfigItem>();
			this.modInfo = modInfo;
		}

		internal void AddConfigItem(BaseConfigItem item)
		{
			configItems.Add(item);
		}
	}
	internal struct ModInfo
	{
		internal string Name { get; set; }

		internal string GUID { get; set; }

		internal string Version { get; set; }
	}
}
namespace LethalConfig.ConfigItems
{
	public abstract class BaseConfigItem
	{
		internal ConfigEntryBase BaseConfigEntry { get; private set; }

		internal bool RequiresRestart { get; private set; }

		internal Mod Owner { get; set; }

		internal string Section => BaseConfigEntry.Definition.Section;

		internal string Name => BaseConfigEntry.Definition.Key;

		internal string Description => BaseConfigEntry.Description.Description;

		internal object CurrentBoxedValue { get; set; }

		internal object OriginalBoxedValue => BaseConfigEntry.BoxedValue;

		internal object BoxedDefaultValue => BaseConfigEntry.DefaultValue;

		internal bool HasValueChanged => !CurrentBoxedValue.Equals(OriginalBoxedValue);

		internal abstract GameObject CreateGameObjectForConfig();

		internal void ApplyChanges()
		{
			BaseConfigEntry.BoxedValue = CurrentBoxedValue;
		}

		internal void CancelChanges()
		{
			CurrentBoxedValue = OriginalBoxedValue;
		}

		internal void ChangeToDefault()
		{
			CurrentBoxedValue = BoxedDefaultValue;
		}

		internal BaseConfigItem(ConfigEntryBase configEntry, BaseOptions options)
		{
			BaseConfigEntry = configEntry;
			RequiresRestart = options.RequiresRestart;
		}
	}
	public abstract class BaseValueConfigItem<T> : BaseConfigItem
	{
		internal ConfigEntry<T> ConfigEntry => (ConfigEntry<T>)(object)base.BaseConfigEntry;

		internal T CurrentValue
		{
			get
			{
				return (T)base.CurrentBoxedValue;
			}
			set
			{
				base.CurrentBoxedValue = value;
			}
		}

		internal T OriginalValue => ConfigEntry.Value;

		internal T Defaultvalue => (T)((ConfigEntryBase)ConfigEntry).DefaultValue;

		internal BaseValueConfigItem(ConfigEntry<T> configEntry, BaseOptions options)
			: base((ConfigEntryBase)(object)configEntry, options)
		{
			CurrentValue = OriginalValue;
		}

		public override string ToString()
		{
			return base.Owner.modInfo.Name + "/" + ((ConfigEntryBase)ConfigEntry).Definition.Section + "/" + ((ConfigEntryBase)ConfigEntry).Definition.Key;
		}
	}
	public class BoolCheckBoxConfigItem : BaseValueConfigItem<bool>
	{
		public BoolCheckBoxConfigItem(ConfigEntry<bool> configEntry, bool requiresRestart = true)
			: base(configEntry, new BaseOptions
			{
				RequiresRestart = requiresRestart
			})
		{
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.BoolCheckBoxPrefab);
		}
	}
	public class EnumDropDownConfigItem<T> : BaseValueConfigItem<T> where T : Enum
	{
		public EnumDropDownConfigItem(ConfigEntry<T> configEntry, bool requiresRestart = true)
			: base(configEntry, new BaseOptions
			{
				RequiresRestart = requiresRestart
			})
		{
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.EnumDropDownPrefab);
		}
	}
	public sealed class FloatInputFieldConfigItem : BaseValueConfigItem<float>
	{
		internal float MaxValue { get; private set; }

		internal float MinValue { get; private set; }

		public FloatInputFieldConfigItem(ConfigEntry<float> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public FloatInputFieldConfigItem(ConfigEntry<float> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public FloatInputFieldConfigItem(ConfigEntry<float> configEntry, FloatInputFieldOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			MinValue = options.Min;
			MaxValue = options.Max;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.FloatInputFieldPrefab);
		}

		private static FloatInputFieldOptions GetDefaultOptions(ConfigEntry<float> configEntry, bool requiresRestart = true)
		{
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			return new FloatInputFieldOptions
			{
				Min = ((acceptableValues as AcceptableValueRange<float>)?.MinValue ?? float.MinValue),
				Max = ((acceptableValues as AcceptableValueRange<float>)?.MaxValue ?? float.MaxValue),
				RequiresRestart = requiresRestart
			};
		}
	}
	public sealed class FloatSliderConfigItem : BaseValueConfigItem<float>
	{
		internal float MaxValue { get; private set; }

		internal float MinValue { get; private set; }

		public FloatSliderConfigItem(ConfigEntry<float> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public FloatSliderConfigItem(ConfigEntry<float> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public FloatSliderConfigItem(ConfigEntry<float> configEntry, FloatSliderOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			MinValue = options.Min;
			MaxValue = options.Max;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.FloatSliderPrefab);
		}

		private static FloatSliderOptions GetDefaultOptions(ConfigEntry<float> configEntry, bool requiresRestart = true)
		{
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			return new FloatSliderOptions
			{
				Min = ((acceptableValues as AcceptableValueRange<float>)?.MinValue ?? 0f),
				Max = ((acceptableValues as AcceptableValueRange<float>)?.MaxValue ?? 100f),
				RequiresRestart = requiresRestart
			};
		}
	}
	public sealed class FloatStepSliderConfigItem : BaseValueConfigItem<float>
	{
		internal float MaxValue { get; private set; }

		internal float MinValue { get; private set; }

		internal float Step { get; private set; }

		public FloatStepSliderConfigItem(ConfigEntry<float> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public FloatStepSliderConfigItem(ConfigEntry<float> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public FloatStepSliderConfigItem(ConfigEntry<float> configEntry, FloatStepSliderOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			_ = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			MinValue = options.Min;
			MaxValue = options.Max;
			Step = options.Step;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.FloatStepSliderPrefab);
		}

		private static FloatStepSliderOptions GetDefaultOptions(ConfigEntry<float> configEntry, bool requiresRestart = true)
		{
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			return new FloatStepSliderOptions
			{
				Min = ((acceptableValues as AcceptableValueRange<float>)?.MinValue ?? 0f),
				Max = ((acceptableValues as AcceptableValueRange<float>)?.MaxValue ?? 100f),
				Step = 0.1f,
				RequiresRestart = requiresRestart
			};
		}
	}
	public sealed class IntInputFieldConfigItem : BaseValueConfigItem<int>
	{
		internal int MaxValue { get; private set; }

		internal int MinValue { get; private set; }

		public IntInputFieldConfigItem(ConfigEntry<int> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public IntInputFieldConfigItem(ConfigEntry<int> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public IntInputFieldConfigItem(ConfigEntry<int> configEntry, IntInputFieldOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			MinValue = options.Min;
			MaxValue = options.Max;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.IntInputFieldPrefab);
		}

		private static IntInputFieldOptions GetDefaultOptions(ConfigEntry<int> configEntry, bool requiresRestart = true)
		{
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			return new IntInputFieldOptions
			{
				Min = ((acceptableValues as AcceptableValueRange<int>)?.MinValue ?? int.MinValue),
				Max = ((acceptableValues as AcceptableValueRange<int>)?.MaxValue ?? int.MaxValue),
				RequiresRestart = requiresRestart
			};
		}
	}
	public sealed class IntSliderConfigItem : BaseValueConfigItem<int>
	{
		internal int MaxValue { get; private set; }

		internal int MinValue { get; private set; }

		public IntSliderConfigItem(ConfigEntry<int> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public IntSliderConfigItem(ConfigEntry<int> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public IntSliderConfigItem(ConfigEntry<int> configEntry, IntSliderOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			MinValue = options.Min;
			MaxValue = options.Max;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.IntSliderPrefab);
		}

		private static IntSliderOptions GetDefaultOptions(ConfigEntry<int> configEntry, bool requiresRestart = true)
		{
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			return new IntSliderOptions
			{
				Min = ((acceptableValues as AcceptableValueRange<int>)?.MinValue ?? 0),
				Max = ((acceptableValues as AcceptableValueRange<int>)?.MaxValue ?? 100),
				RequiresRestart = requiresRestart
			};
		}
	}
	public sealed class TextInputFieldConfigItem : BaseValueConfigItem<string>
	{
		internal int CharacterLimit { get; private set; }

		public TextInputFieldConfigItem(ConfigEntry<string> configEntry)
			: this(configEntry, requiresRestart: true)
		{
		}

		public TextInputFieldConfigItem(ConfigEntry<string> configEntry, bool requiresRestart)
			: this(configEntry, GetDefaultOptions(configEntry, requiresRestart))
		{
		}

		public TextInputFieldConfigItem(ConfigEntry<string> configEntry, TextInputFieldOptions options)
			: base(configEntry, (BaseOptions)options)
		{
			CharacterLimit = options.CharacterLimit;
		}

		internal override GameObject CreateGameObjectForConfig()
		{
			return Object.Instantiate<GameObject>(Prefabs.TextInputFieldPrefab);
		}

		private static TextInputFieldOptions GetDefaultOptions(ConfigEntry<string> configEntry, bool requiresRestart = true)
		{
			return new TextInputFieldOptions
			{
				CharacterLimit = 0,
				RequiresRestart = requiresRestart
			};
		}
	}
}
namespace LethalConfig.ConfigItems.Options
{
	public class BaseOptions
	{
		public bool RequiresRestart { get; set; } = true;

	}
	public sealed class FloatInputFieldOptions : BaseOptions
	{
		public float Min { get; set; } = float.MinValue;


		public float Max { get; set; } = float.MaxValue;

	}
	public class FloatSliderOptions : BaseOptions
	{
		public float Min { get; set; }

		public float Max { get; set; } = 1f;

	}
	public class FloatStepSliderOptions : FloatSliderOptions
	{
		public float Step { get; set; } = 0.1f;

	}
	public sealed class IntInputFieldOptions : BaseOptions
	{
		public int Min { get; set; } = int.MinValue;


		public int Max { get; set; } = int.MaxValue;

	}
	public sealed class IntSliderOptions : BaseOptions
	{
		public int Min { get; set; }

		public int Max { get; set; } = 100;

	}
	public sealed class TextInputFieldOptions : BaseOptions
	{
		public int CharacterLimit { get; set; }
	}
}

BepInEx/plugins/LethalConfig/SharedUtils.dll

Decompiled 8 months ago
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		MonoScriptData result = default(MonoScriptData);
		result.FilePathsData = new byte[85]
		{
			0, 0, 0, 1, 0, 0, 0, 34, 92, 65,
			115, 115, 101, 116, 115, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 83, 104, 97, 114, 101, 100,
			92, 76, 111, 103, 85, 116, 105, 108, 115, 46,
			99, 115, 0, 0, 0, 1, 0, 0, 0, 35,
			92, 65, 115, 115, 101, 116, 115, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 83, 104, 97, 114,
			101, 100, 92, 80, 97, 116, 104, 85, 116, 105,
			108, 115, 46, 99, 115
		};
		result.TypesData = new byte[51]
		{
			0, 0, 0, 0, 20, 83, 104, 97, 114, 101,
			100, 85, 116, 105, 108, 115, 124, 76, 111, 103,
			85, 116, 105, 108, 115, 0, 0, 0, 0, 21,
			83, 104, 97, 114, 101, 100, 85, 116, 105, 108,
			115, 124, 80, 97, 116, 104, 85, 116, 105, 108,
			115
		};
		result.TotalFiles = 2;
		result.TotalTypes = 2;
		result.IsEditorOnly = false;
		return result;
	}
}
namespace SharedUtils;

public static class LogUtils
{
	private static Dictionary<Assembly, ManualLogSource> logSources = new Dictionary<Assembly, ManualLogSource>();

	public static void Init(string pluginGuid)
	{
		Assembly callingAssembly = Assembly.GetCallingAssembly();
		if (!logSources.ContainsKey(callingAssembly))
		{
			logSources.Add(callingAssembly, Logger.CreateLogSource(pluginGuid));
		}
	}

	public static void LogInfo(string message)
	{
		logSources[Assembly.GetCallingAssembly()].LogInfo((object)message);
	}

	public static void LogWarning(string message)
	{
		logSources[Assembly.GetCallingAssembly()].LogWarning((object)message);
	}

	public static void LogError(string message)
	{
		logSources[Assembly.GetCallingAssembly()].LogError((object)message);
	}

	public static void LogFatal(string message)
	{
		logSources[Assembly.GetCallingAssembly()].LogFatal((object)message);
	}
}
public static class PathUtils
{
	public static string PathForResourceInAssembly(string resourceName, Assembly assembly = null)
	{
		return Path.Combine(Path.GetDirectoryName((assembly ?? Assembly.GetCallingAssembly()).Location), resourceName);
	}
}

BepInEx/plugins/Suit Saver.dll

Decompiled 8 months ago
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Suit Saver")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Suit Saver")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cb7cfb30-b06e-4e41-9de7-03640e1662ea")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SuitSaver
{
	[BepInPlugin("Hexnet.lethalcompany.suitsaver", "Suit Saver", "1.1.2")]
	public class SuitSaver : BaseUnityPlugin
	{
		private const string modGUID = "Hexnet.lethalcompany.suitsaver";

		private const string modName = "Suit Saver";

		private const string modVersion = "1.1.2";

		private readonly Harmony harmony = new Harmony("Hexnet.lethalcompany.suitsaver");

		private void Awake()
		{
			harmony.PatchAll();
			Debug.Log((object)"[SS]: Suit Saver loaded successfully!");
		}
	}
}
namespace SuitSaver.Patches
{
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartPatch
		{
			[HarmonyPatch("ResetShip")]
			[HarmonyPostfix]
			private static void ResetShipPatch()
			{
				Debug.Log((object)"[SS]: Ship has been reset!");
				Debug.Log((object)"[SS]: Reloading suit...");
				LoadSuitFromFile();
			}
		}

		[HarmonyPatch(typeof(UnlockableSuit))]
		internal class SuitPatch
		{
			[HarmonyPatch("SwitchSuitClientRpc")]
			[HarmonyPostfix]
			private static void SyncSuit(ref UnlockableSuit __instance, int playerID)
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				int num = (int)localPlayerController.playerClientId;
				if (playerID != num)
				{
					UnlockableSuit.SwitchSuitForPlayer(StartOfRound.Instance.allPlayerScripts[playerID], __instance.syncedSuitID.Value, true);
				}
			}

			[HarmonyPatch("SwitchSuitToThis")]
			[HarmonyPostfix]
			private static void EquipSuitPatch()
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[localPlayerController.currentSuitID].unlockableName;
				SaveToFile(unlockableName);
				Debug.Log((object)("[SS]: Successfully saved current suit. (" + unlockableName + ")"));
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		internal class JoinGamePatch
		{
			[HarmonyPatch("ConnectClientToPlayerObject")]
			[HarmonyPostfix]
			private static void LoadSuitPatch(ref PlayerControllerB __instance)
			{
				((Component)GameNetworkManager.Instance.localPlayerController).gameObject.AddComponent<EquipAfterSyncPatch>();
			}
		}

		internal class EquipAfterSyncPatch : MonoBehaviour
		{
			private void Start()
			{
				((MonoBehaviour)this).StartCoroutine(LoadSuit());
			}

			private IEnumerator LoadSuit()
			{
				Debug.Log((object)"[SS]: Waiting for suits to sync...");
				yield return (object)new WaitForSeconds(1f);
				LoadSuitFromFile();
			}
		}

		public static string SavePath = Application.persistentDataPath + "\\suitsaver.txt";

		private static void SaveToFile(string suitName)
		{
			File.WriteAllText(SavePath, suitName);
		}

		private static string LoadFromFile()
		{
			if (File.Exists(SavePath))
			{
				return File.ReadAllText(SavePath);
			}
			return "-1";
		}

		private static UnlockableSuit GetSuitByName(string Name)
		{
			List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables;
			UnlockableSuit[] array = Resources.FindObjectsOfTypeAll<UnlockableSuit>();
			foreach (UnlockableSuit val in array)
			{
				if (val.syncedSuitID.Value >= 0)
				{
					string unlockableName = unlockables[val.syncedSuitID.Value].unlockableName;
					if (unlockableName == Name)
					{
						return val;
					}
				}
			}
			return null;
		}

		private static void LoadSuitFromFile()
		{
			string text = LoadFromFile();
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!(text == "-1"))
			{
				UnlockableSuit suitByName = GetSuitByName(text);
				if ((Object)(object)suitByName != (Object)null)
				{
					UnlockableSuit.SwitchSuitForPlayer(localPlayerController, suitByName.syncedSuitID.Value, false);
					suitByName.SwitchSuitServerRpc((int)localPlayerController.playerClientId);
					Debug.Log((object)("[SS]: Successfully loaded saved suit. (" + text + ")"));
				}
				else
				{
					Debug.Log((object)("[SS]: Failed to load saved suit. Perhaps it's locked? (" + text + ")"));
				}
			}
		}
	}
}

BepInEx/plugins/LethalAPI.Terminal.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalAPI.LibTerminal.Attributes;
using LethalAPI.LibTerminal.Commands;
using LethalAPI.LibTerminal.Interfaces;
using LethalAPI.LibTerminal.Models;
using LethalAPI.LibTerminal.Models.Enums;
using LethalAPI.LibTerminal.Patches;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ShimmyMySherbet, LethalAPI Modding Team")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A library that allows the creation of custom terminal commands for Lethal Company mods")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d6f96cfefb42ad90f112bc5c08f28bece2e13680")]
[assembly: AssemblyProduct("LethalAPI.Terminal")]
[assembly: AssemblyTitle("LethalAPI.Terminal")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/LethalCompany/LethalAPI.Terminal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalAPI.LibTerminal
{
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal static class ParseSentencePatch
	{
		[HarmonyPrefix]
		public static bool ParsePrefix(Terminal __instance, ref TerminalNode __state)
		{
			__state = null;
			string command = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
			__state = CommandHandler.HandleCommandInput(command, __instance);
			return (Object)(object)__state == (Object)null;
		}

		[HarmonyPostfix]
		public static TerminalNode ParsePostfix(TerminalNode __result, TerminalNode __state, Terminal __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((Object)(object)__state != (Object)null)
			{
				TerminalSubmitPatch.LastNode = __state;
				return __state;
			}
			if ((int)__instance.videoPlayer.source == 1)
			{
				__instance.videoPlayer.source = (VideoSource)0;
			}
			TerminalSubmitPatch.LastNode = __result;
			return __result;
		}
	}
	public static class TerminalExtensions
	{
		public static void PlayVideoFile(this Terminal terminal, string filePath)
		{
			string url = "file:///" + filePath.Replace('\\', '/');
			terminal.PlayVideoLink(url);
		}

		public static void PlayVideoLink(this Terminal terminal, Uri url)
		{
			((MonoBehaviour)terminal).StartCoroutine(PlayVideoLink(url.AbsoluteUri, terminal));
		}

		public static void PlayVideoLink(this Terminal terminal, string url)
		{
			((MonoBehaviour)terminal).StartCoroutine(PlayVideoLink(url, terminal));
		}

		private static IEnumerator PlayVideoLink(string url, Terminal terminal)
		{
			yield return (object)new WaitForFixedUpdate();
			((Behaviour)terminal.terminalImage).enabled = true;
			terminal.terminalImage.texture = (Texture)(object)terminal.videoTexture;
			terminal.displayingPersistentImage = null;
			terminal.videoPlayer.clip = null;
			terminal.videoPlayer.source = (VideoSource)1;
			terminal.videoPlayer.url = url;
			((Behaviour)terminal.videoPlayer).enabled = true;
		}

		public static TerminalNode GetLastLoadedNode()
		{
			return LoadNewNodePatch.LastLoadedNode;
		}

		public static TerminalNode GetLastLoadedNode(this Terminal terminal)
		{
			return LoadNewNodePatch.LastLoadedNode ?? terminal.currentNode;
		}
	}
	[BepInPlugin("LethalAPI.Terminal", "LethalAPI.Terminal", "1.0.0")]
	internal class TerminalLibPlugin : BaseUnityPlugin
	{
		private Harmony HarmonyInstance = new Harmony("LethalAPI.Terminal");

		private TerminalModRegistry Terminal;

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalAPI.Terminal is loading...");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Installing patches");
			HarmonyInstance.PatchAll(typeof(TerminalLibPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registering built-in Commands");
			Terminal = TerminalRegistry.CreateTerminalRegistry();
			Terminal.RegisterFrom<CommandInfoCommands>();
			Object.DontDestroyOnLoad((Object)(object)this);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalAPI.Terminal is loaded!");
		}
	}
	public static class TerminalNodeExtensions
	{
		public static TerminalNode WithDisplayText(this TerminalNode node, object displayText)
		{
			node.displayText = displayText.ToString();
			return node;
		}

		public static TerminalNode WithDisplayTexture(this TerminalNode node, Texture texture)
		{
			node.displayTexture = texture;
			return node;
		}

		public static TerminalNode WithVideoClip(this TerminalNode node, VideoClip video)
		{
			node.displayVideo = video;
			return node;
		}

		public static TerminalNode WithAcceptsAnything(this TerminalNode node)
		{
			node.acceptAnything = true;
			return node;
		}

		public static TerminalNode WithBuyItemIndex(this TerminalNode node, int index)
		{
			node.buyItemIndex = index;
			return node;
		}

		public static TerminalNode WithMoonIndex(this TerminalNode node, int index)
		{
			node.buyRerouteToMoon = index;
			return node;
		}

		public static TerminalNode ClearText(this TerminalNode node)
		{
			node.clearPreviousText = true;
			return node;
		}

		public static TerminalNode WithItemCost(this TerminalNode node, int cost)
		{
			node.itemCost = cost;
			return node;
		}

		public static TerminalNode LoadImageSlowly(this TerminalNode node)
		{
			node.loadImageSlowly = true;
			return node;
		}

		public static TerminalNode PersistImage(this TerminalNode node)
		{
			node.persistentImage = true;
			return node;
		}

		public static TerminalNode WithAudio(this TerminalNode node, AudioClip audio)
		{
			node.playClip = audio;
			return node;
		}

		public static TerminalNode WithTerminalEvent(this TerminalNode node, string eventName)
		{
			node.terminalEvent = eventName;
			return node;
		}

		public static TerminalNode ReturnItemFromStorage(this TerminalNode node, int unlockID)
		{
			node.shipUnlockableID = unlockID;
			node.returnFromStorage = true;
			return node;
		}

		public static TerminalNode PlayEffect(this TerminalNode node, SyncedTerminalClip clip)
		{
			node.playSyncedClip = (int)clip;
			return node;
		}

		public static TerminalNode PlayError(this TerminalNode node)
		{
			node.playSyncedClip = 1;
			return node;
		}
	}
	public class TerminalRegistry
	{
		private static readonly ConcurrentDictionary<string, List<TerminalCommand>> m_RegisteredCommands = new ConcurrentDictionary<string, List<TerminalCommand>>(StringComparer.InvariantCultureIgnoreCase);

		public static TerminalModRegistry RegisterFrom<T>(T instance) where T : class
		{
			TerminalModRegistry terminalModRegistry = new TerminalModRegistry();
			terminalModRegistry.RegisterFrom(instance);
			return terminalModRegistry;
		}

		public static TerminalModRegistry CreateTerminalRegistry()
		{
			return new TerminalModRegistry();
		}

		public static void RegisterCommand(TerminalCommand command)
		{
			if (!m_RegisteredCommands.TryGetValue(command.Name, out var value))
			{
				value = new List<TerminalCommand>();
				m_RegisteredCommands[command.Name] = value;
			}
			lock (value)
			{
				value.Add(command);
			}
		}

		public static void Deregister(TerminalCommand command)
		{
			if (!m_RegisteredCommands.TryGetValue(command.Name, out var value))
			{
				return;
			}
			lock (value)
			{
				value.Remove(command);
			}
		}

		public static IReadOnlyList<TerminalCommand> GetCommands(string commandName)
		{
			if (m_RegisteredCommands.TryGetValue(commandName, out var value))
			{
				return value;
			}
			return new List<TerminalCommand>();
		}

		public static IEnumerable<TerminalCommand> EnumerateCommands(string name)
		{
			if (!m_RegisteredCommands.TryGetValue(name, out var value))
			{
				return Enumerable.Empty<TerminalCommand>();
			}
			return value;
		}

		public static IEnumerable<TerminalCommand> EnumerateCommands()
		{
			string[] keys = m_RegisteredCommands.Keys.ToArray();
			for (int i = 0; i < keys.Length; i++)
			{
				List<TerminalCommand> overloads = m_RegisteredCommands[keys[i]];
				for (int c = 0; c < overloads.Count; c++)
				{
					yield return overloads[c];
				}
			}
		}

		public static IEnumerable<MethodInfo> GetCommandMethods<T>()
		{
			MethodInfo[] methods = typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo method in methods)
			{
				if (method.GetCustomAttribute<TerminalCommandAttribute>() != null)
				{
					yield return method;
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalAPI.Terminal";

		public const string PLUGIN_NAME = "LethalAPI.Terminal";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalAPI.LibTerminal.Patches
{
	[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
	internal static class BeginUsingTerminalPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Terminal __instance)
		{
			ITerminalInterface currentInterface = CommandHandler.CurrentInterface;
			if (currentInterface != null)
			{
				TerminalNode splashScreen = currentInterface.GetSplashScreen(__instance);
				if ((Object)(object)splashScreen != (Object)null)
				{
					__instance.LoadNewNode(splashScreen);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
	internal static class LoadNewNodePatch
	{
		public static TerminalNode LastLoadedNode { get; private set; }

		[HarmonyPrefix]
		public static void Prefix(TerminalNode node)
		{
			LastLoadedNode = node;
		}
	}
	[HarmonyPatch(typeof(Terminal), "selectTextFieldDelayed")]
	internal static class SelectTextFieldPatch
	{
		[HarmonyPrefix]
		public static bool Prefix()
		{
			return false;
		}

		[HarmonyPostfix]
		public static void Postfix(Terminal __instance, ref IEnumerator __result)
		{
			__result = Patch(__instance);
		}

		private static IEnumerator Patch(Terminal terminal)
		{
			yield return (object)new WaitForSeconds(0.2f);
			terminal.screenText.ActivateInputField();
			((Selectable)terminal.screenText).Select();
		}
	}
	[HarmonyPatch(typeof(Terminal), "OnSubmit")]
	internal static class TerminalSubmitPatch
	{
		private static ManualLogSource m_LogSource = new ManualLogSource("LethalAPI.Terminal");

		public static TerminalNode LastNode { get; set; }

		[HarmonyPrefix]
		public static void Prefix()
		{
			LastNode = null;
		}

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			CodeInstruction[] array = instructions.ToArray();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (!(array[num].opcode != OpCodes.Callvirt))
				{
					if (array[num + 1].opcode != OpCodes.Ldarg_0)
					{
						ReportTranspileError("Ldarg_0 expected after final callVirt, not found");
						return array;
					}
					array[num + 1] = new CodeInstruction(OpCodes.Ret, (object)null);
					return array;
				}
			}
			ReportTranspileError("Failed to find Callvirt in backward scan");
			return array;
		}

		private static void ReportTranspileError(string message)
		{
			m_LogSource.LogError((object)("Failed to transpile OnSubmit to remove Scroll To Bottom. Did the method get modified in an update? (" + message + ")"));
			m_LogSource.LogWarning((object)"This won't break the mod, but it will cause some odd terminal scrolling behavior");
		}

		[HarmonyPostfix]
		public static void Postfix(Terminal __instance, ref Coroutine ___forceScrollbarCoroutine)
		{
			if ((Object)(object)LastNode == (Object)null || LastNode.clearPreviousText)
			{
				ExecuteScrollCoroutine(__instance, ref ___forceScrollbarCoroutine);
			}
			else
			{
				((MonoBehaviour)__instance).StartCoroutine("forceScrollbarDown");
			}
		}

		private static void ExecuteScrollCoroutine(Terminal terminal, ref Coroutine forceScrollbarCoroutine)
		{
			if (forceScrollbarCoroutine != null)
			{
				((MonoBehaviour)terminal).StopCoroutine(forceScrollbarCoroutine);
			}
			forceScrollbarCoroutine = ((MonoBehaviour)terminal).StartCoroutine("forceScrollbarUp");
		}
	}
	[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
	internal static class TextPostProcessPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Terminal __instance, ref string modifiedDisplayText, ref string __state)
		{
			__state = null;
			if (CommandHandler.CurrentInterface == null || CommandHandler.CurrentInterface.APITextPostProcessing)
			{
				modifiedDisplayText = TextUtil.PostProcessResponse(__instance, modifiedDisplayText);
				return true;
			}
			bool flag = ProcessInterface(CommandHandler.CurrentInterface, ref modifiedDisplayText, __instance);
			if (!flag)
			{
				__state = modifiedDisplayText;
			}
			return flag;
		}

		[HarmonyPostfix]
		public static string Postfix(string __result, Terminal __instance, string __state)
		{
			string text = __state ?? __result;
			if (CommandHandler.CurrentInterface != null)
			{
				text = CommandHandler.CurrentInterface.PostProcessText(__instance, text);
			}
			return text;
		}

		private static bool ProcessInterface(ITerminalInterface terminalInterface, ref string modifiedDisplayText, Terminal terminal)
		{
			if (terminalInterface.APITextPostProcessing)
			{
				modifiedDisplayText = modifiedDisplayText.TrimStart('\n', ' ').SetEndPadding('\n', 2);
			}
			modifiedDisplayText = terminalInterface.PreProcessText(terminal, modifiedDisplayText);
			return terminalInterface.VanillaTextPostProcessing;
		}
	}
}
namespace LethalAPI.LibTerminal.Models
{
	public class ArgumentStream
	{
		public string[] Arguments { get; }

		public int Index { get; set; } = 0;


		public bool EndOfStream => Index >= Arguments.Length;

		public ArgumentStream(string[] arguments)
		{
			Arguments = arguments;
		}

		public ArgumentStream(IEnumerable<string> arguments)
		{
			Arguments = arguments.ToArray();
		}

		public void Reset()
		{
			Index = 0;
		}

		public bool TryReadNext(Type type, out object value)
		{
			if (EndOfStream)
			{
				value = null;
				return false;
			}
			return StringConverter.TryConvert(Arguments[Index++], type, out value);
		}

		public bool TryReadRemaining(out string result)
		{
			if (EndOfStream)
			{
				result = null;
				return false;
			}
			result = string.Join(" ", Arguments.Skip(Index));
			return true;
		}

		public bool TryReadNext(out string value)
		{
			value = string.Empty;
			if (EndOfStream)
			{
				return false;
			}
			value = Arguments[Index++];
			return true;
		}

		public bool TryReadNext(out sbyte value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return sbyte.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out byte value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return byte.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out short value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return short.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out ushort value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return ushort.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out int value)
		{
			value = 0;
			if (EndOfStream)
			{
				return false;
			}
			return int.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out uint value)
		{
			value = 0u;
			if (EndOfStream)
			{
				return false;
			}
			return uint.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out long value)
		{
			value = 0L;
			if (EndOfStream)
			{
				return false;
			}
			return long.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out ulong value)
		{
			value = 0uL;
			if (EndOfStream)
			{
				return false;
			}
			return ulong.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out float value)
		{
			value = 0f;
			if (EndOfStream)
			{
				return false;
			}
			return float.TryParse(Arguments[Index++], out value);
		}

		public bool TryReadNext(out double value)
		{
			value = 0.0;
			if (EndOfStream)
			{
				return false;
			}
			return double.TryParse(Arguments[Index++], out value);
		}
	}
	public static class CommandActivator
	{
		public static bool TryCreateInvoker(ArgumentStream arguments, ServiceCollection services, MethodInfo method, out Func<object, object> invoker)
		{
			TerminalCommandAttribute commandAttribute = method.GetCustomAttribute<TerminalCommandAttribute>();
			ParameterInfo[] parameters = method.GetParameters();
			object[] values = new object[parameters.Length];
			invoker = null;
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				Type parameterType = parameterInfo.ParameterType;
				if (services.TryGetService(parameterType, out var service))
				{
					values[i] = service;
				}
				else if (parameterType == typeof(string) && parameterInfo.GetCustomAttribute<RemainingTextAttribute>() != null)
				{
					if (!arguments.TryReadRemaining(out var result))
					{
						return false;
					}
					values[i] = result;
				}
				else
				{
					if (!arguments.TryReadNext(parameterType, out var value))
					{
						return false;
					}
					values[i] = value;
				}
			}
			arguments.Reset();
			invoker = (object instance) => ExecuteCommand(method, instance, values, commandAttribute?.ClearText ?? false);
			return true;
		}

		private static object ExecuteCommand(MethodInfo method, object instance, object[] arguments, bool clearConsole)
		{
			object obj;
			try
			{
				obj = method.Invoke(instance, arguments);
			}
			catch (Exception ex)
			{
				Console.WriteLine("Error caught while invoking command hander: " + ex.Message);
				Console.WriteLine(ex.StackTrace);
				return null;
			}
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			if (typeof(TerminalNode).IsAssignableFrom(type))
			{
				return obj;
			}
			if (typeof(ITerminalInteraction).IsAssignableFrom(type))
			{
				return obj;
			}
			if (typeof(ITerminalInterface).IsAssignableFrom(type))
			{
				return obj;
			}
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.displayText = obj.ToString() + "\n";
			val.clearPreviousText = clearConsole;
			return val;
		}
	}
	public class CommandComparer : IComparer<TerminalCommand>
	{
		public int Compare(TerminalCommand x, TerminalCommand y)
		{
			if (x.Priority > y.Priority)
			{
				return 1;
			}
			if (x.Priority < y.Priority)
			{
				return -1;
			}
			return x.ArgumentCount.CompareTo(y.ArgumentCount);
		}
	}
	public static class CommandHandler
	{
		private static readonly Stack<ITerminalInteraction> m_Interactions = new Stack<ITerminalInteraction>();

		private static readonly Regex m_SplitRegex = new Regex("[\\\"](.+?)[\\\"]|([^ ]+)", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);

		private static readonly CommandComparer m_Comparer = new CommandComparer();

		public static int InteractionDepth => m_Interactions.Count;

		public static ITerminalInterface CurrentInterface { get; private set; }

		public static TerminalNode HandleCommandInput(string command, Terminal terminal)
		{
			MatchCollection source = m_SplitRegex.Matches(command.Trim());
			string[] array = (from Match x in source
				select x.Value.Trim('"', ' ')).ToArray();
			ArgumentStream arguments = new ArgumentStream(array);
			if (CurrentInterface != null)
			{
				return CurrentInterface.HandleInput(terminal, arguments);
			}
			TerminalNode val = ExecuteInteractions(arguments, terminal);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			string commandName = array.First();
			ArgumentStream arguments2 = new ArgumentStream(array.Skip(1));
			return ExecuteCommand(commandName, arguments2, terminal);
		}

		public static TerminalNode ExecuteInteractions(ArgumentStream arguments, Terminal terminal)
		{
			while (m_Interactions.Count > 0)
			{
				ITerminalInteraction terminalInteraction = m_Interactions.Pop();
				arguments.Reset();
				try
				{
					terminalInteraction.Services.WithServices(arguments, terminal, arguments.Arguments);
					object obj = terminalInteraction.HandleTerminalResponse(arguments);
					if (obj != null)
					{
						return HandleCommandResult(obj, terminal);
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.GetType().Name);
					Console.WriteLine("Error executing interaction: " + ex.Message + ", " + ex.StackTrace);
				}
			}
			return null;
		}

		public static TerminalNode ExecuteCommand(ArgumentStream arguments, Terminal terminal)
		{
			arguments.Reset();
			if (!arguments.TryReadNext(out string value))
			{
				return null;
			}
			ArgumentStream arguments2 = new ArgumentStream(arguments.Arguments.Skip(1));
			return ExecuteCommand(value, arguments2, terminal);
		}

		public static TerminalNode ExecuteCommand(string commandName, ArgumentStream arguments, Terminal terminal)
		{
			List<(TerminalCommand, Func<TerminalNode>)> list = new List<(TerminalCommand, Func<TerminalNode>)>();
			TerminalCommand[] array = TerminalRegistry.GetCommands(commandName).ToArray();
			ServiceCollection services = new ServiceCollection(arguments, arguments.Arguments, terminal);
			foreach (TerminalCommand terminalCommand in array)
			{
				if (!terminalCommand.CheckAllowed())
				{
					continue;
				}
				arguments.Reset();
				if (terminalCommand.TryCreateInvoker(arguments, services, out var invoker))
				{
					Func<TerminalNode> item = () => HandleCommandResult(invoker(), terminal);
					list.Add((terminalCommand, item));
				}
			}
			IOrderedEnumerable<(TerminalCommand, Func<TerminalNode>)> orderedEnumerable = list.OrderByDescending<(TerminalCommand, Func<TerminalNode>), TerminalCommand>(((TerminalCommand command, Func<TerminalNode> invoker) x) => x.command, m_Comparer);
			foreach (var item4 in orderedEnumerable)
			{
				TerminalCommand item2 = item4.Item1;
				Func<TerminalNode> item3 = item4.Item2;
				TerminalNode val = item3();
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static TerminalNode HandleCommandResult(object result, Terminal terminal)
		{
			TerminalNode val = (TerminalNode)((result is TerminalNode) ? result : null);
			if (val != null)
			{
				return val;
			}
			if (result is ITerminalInteraction terminalInteraction)
			{
				SetInteraction(terminalInteraction);
				return terminalInteraction.Prompt;
			}
			if (result is ITerminalInterface terminalInterface)
			{
				SetInterface(terminalInterface);
				return terminalInterface.GetSplashScreen(terminal);
			}
			return ScriptableObject.CreateInstance<TerminalNode>().WithDisplayText(result);
		}

		public static void SetInteraction(ITerminalInteraction interaction)
		{
			m_Interactions.Push(interaction);
		}

		public static void SetInterface(ITerminalInterface terminalInterface)
		{
			CurrentInterface = terminalInterface;
		}

		public static void ResetInterface()
		{
			CurrentInterface = null;
		}

		public static void ResetInterface<T>() where T : ITerminalInterface
		{
			if (CurrentInterface != null && CurrentInterface is T)
			{
				ResetInterface();
			}
		}
	}
	public static class DefaultStringConverters
	{
		[StringConverter]
		public static string ParseString(string input)
		{
			return input;
		}

		[StringConverter]
		public static sbyte ParseSByte(string input)
		{
			if (sbyte.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static byte ParseByte(string input)
		{
			if (byte.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static short ParseShort(string input)
		{
			if (short.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static ushort ParseUShort(string input)
		{
			if (ushort.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static int ParseInt(string input)
		{
			if (int.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static uint ParseUInt(string input)
		{
			if (uint.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static long ParseLong(string input)
		{
			if (long.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static ulong ParseULong(string input)
		{
			if (ulong.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static float ParseFloat(string input)
		{
			if (float.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static double ParseDouble(string input)
		{
			if (double.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static decimal ParseDecimal(string input)
		{
			if (decimal.TryParse(input, out var result))
			{
				return result;
			}
			throw new ArgumentException();
		}

		[StringConverter]
		public static PlayerControllerB ParsePlayerControllerB(string value)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				throw new ArgumentException("Game has not started");
			}
			PlayerControllerB val = null;
			if (ulong.TryParse(value, out var steamID))
			{
				val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.playerSteamId == steamID));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => x.playerUsername.IndexOf(value, StringComparison.InvariantCultureIgnoreCase) != -1));
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException("Failed to find player");
			}
			return val;
		}
	}
	public readonly struct RegisteredStringConverter
	{
		public Type Type { get; }

		public StringConversionHandler Handler { get; }

		public RegisteredStringConverter(Type type, StringConversionHandler handler)
		{
			Type = type;
			Handler = handler;
		}
	}
	public struct ServiceCollection
	{
		private Dictionary<Type, object> m_Services;

		public ServiceCollection(params object[] services)
		{
			m_Services = new Dictionary<Type, object>();
			WithServices(services);
		}

		public ServiceCollection()
		{
			m_Services = new Dictionary<Type, object>();
		}

		public bool TryGetService(Type t, out object service)
		{
			if (m_Services == null)
			{
				service = null;
				return false;
			}
			return m_Services.TryGetValue(t, out service);
		}

		public void WithService<T>(T instance)
		{
			if (m_Services != null)
			{
				m_Services[typeof(T)] = instance;
			}
		}

		public void WithServices(params object[] services)
		{
			if (m_Services == null)
			{
				return;
			}
			foreach (object obj in services)
			{
				if (obj != null)
				{
					m_Services.Add(obj.GetType(), obj);
				}
			}
		}
	}
	public delegate object StringConversionHandler(string value);
	public static class StringConverter
	{
		private static bool m_Initialized = false;

		private static ConcurrentDictionary<Type, List<StringConversionHandler>> m_StringConverters { get; } = new ConcurrentDictionary<Type, List<StringConversionHandler>>();


		public static bool TryConvert(string value, Type type, out object result)
		{
			if (!m_Initialized)
			{
				m_Initialized = true;
				RegisterFromType(typeof(DefaultStringConverters));
			}
			if (!m_StringConverters.TryGetValue(type, out var value2))
			{
				result = null;
				return false;
			}
			for (int i = 0; i < value2.Count; i++)
			{
				try
				{
					result = value2[i](value);
					return true;
				}
				catch (Exception)
				{
				}
			}
			result = null;
			return false;
		}

		public static List<RegisteredStringConverter> RegisterFrom<T>(T instance) where T : class
		{
			return RegisterFromType(typeof(T), instance);
		}

		public static bool Deregister(RegisteredStringConverter converter)
		{
			if (!m_StringConverters.TryGetValue(converter.Type, out var value))
			{
				return false;
			}
			return value.Remove(converter.Handler);
		}

		public static bool CanConvert(Type type)
		{
			return m_StringConverters.ContainsKey(type);
		}

		public static List<RegisteredStringConverter> RegisterFromType(Type type, object instance = null)
		{
			List<RegisteredStringConverter> list = new List<RegisteredStringConverter>();
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo method in methods)
			{
				if (method.GetCustomAttribute<StringConverterAttribute>() == null)
				{
					continue;
				}
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(string)))
				{
					Type returnType = method.ReturnType;
					StringConversionHandler stringConversionHandler = (string value) => method.Invoke(instance, new object[1] { value });
					if (!m_StringConverters.TryGetValue(returnType, out var value2))
					{
						value2 = new List<StringConversionHandler>();
						m_StringConverters[returnType] = value2;
					}
					value2.Add(stringConversionHandler);
					list.Add(new RegisteredStringConverter(returnType, stringConversionHandler));
				}
			}
			return list;
		}
	}
	public class TerminalCommand
	{
		private ManualLogSource m_LogSource = new ManualLogSource("LethalAPI.Terminal");

		public string Name { get; }

		public MethodInfo Method { get; }

		public object Instance { get; }

		public bool ClearConsole { get; }

		public int ArgumentCount { get; }

		public string Syntax { get; }

		public string Description { get; }

		public int Priority { get; }

		public TerminalCommand(string name, MethodInfo method, object instance, bool clearConsole, string syntax = null, string description = null, int priority = 0)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Name = name;
			Method = method;
			Instance = instance;
			ClearConsole = clearConsole;
			ArgumentCount = method.GetParameters().Length;
			Syntax = syntax;
			Description = description;
			Priority = priority;
		}

		public bool CheckAllowed()
		{
			IEnumerable<AccessControlAttribute> customAttributes = Method.GetCustomAttributes<AccessControlAttribute>();
			foreach (AccessControlAttribute item in customAttributes)
			{
				if (!item.CheckAllowed())
				{
					return false;
				}
			}
			return true;
		}

		public static TerminalCommand FromMethod(MethodInfo info, object instance, string overrideName = null)
		{
			bool clearConsole = false;
			string syntax = null;
			string description = null;
			string text = overrideName;
			int priority = 0;
			TerminalCommandAttribute customAttribute = info.GetCustomAttribute<TerminalCommandAttribute>();
			if (customAttribute != null)
			{
				text = text ?? customAttribute.CommandName;
				clearConsole = customAttribute.ClearText;
			}
			CommandInfoAttribute customAttribute2 = info.GetCustomAttribute<CommandInfoAttribute>();
			if (customAttribute2 != null)
			{
				syntax = customAttribute2.Syntax;
				description = customAttribute2.Description;
			}
			CommandPriority customAttribute3 = info.GetCustomAttribute<CommandPriority>();
			if (customAttribute3 != null)
			{
				priority = customAttribute3.Priority;
			}
			return new TerminalCommand(text, info, instance, clearConsole, syntax, description, priority);
		}

		public bool TryCreateInvoker(ArgumentStream arguments, ServiceCollection services, out Func<object> invoker)
		{
			if (CommandActivator.TryCreateInvoker(arguments, services, Method, out var activatedInvoker))
			{
				invoker = () => activatedInvoker(Instance);
				return true;
			}
			invoker = null;
			return false;
		}
	}
	public class TerminalModRegistry
	{
		public List<TerminalCommand> Commands { get; } = new List<TerminalCommand>();


		public List<RegisteredStringConverter> StringConverters { get; } = new List<RegisteredStringConverter>();


		public T RegisterFrom<T>() where T : class, new()
		{
			return RegisterFrom(new T());
		}

		public T RegisterFrom<T>(T instance) where T : class
		{
			foreach (MethodInfo commandMethod in TerminalRegistry.GetCommandMethods<T>())
			{
				TerminalCommand terminalCommand = TerminalCommand.FromMethod(commandMethod, instance);
				TerminalRegistry.RegisterCommand(terminalCommand);
				lock (Commands)
				{
					Commands.Add(terminalCommand);
				}
			}
			StringConverters.AddRange(StringConverter.RegisterFrom(instance));
			return instance;
		}

		public void Deregister()
		{
			for (int i = 0; i < Commands.Count; i++)
			{
				TerminalRegistry.Deregister(Commands[i]);
			}
			Commands.Clear();
			for (int j = 0; j < StringConverters.Count; j++)
			{
				StringConverter.Deregister(StringConverters[j]);
			}
			StringConverters.Clear();
		}
	}
	public static class TextUtil
	{
		public static string PostProcessResponse(Terminal terminal, string message)
		{
			TerminalNode lastLoadedNode = terminal.GetLastLoadedNode();
			message = ((lastLoadedNode == null || !lastLoadedNode.clearPreviousText) ? message.TrimStart('\n', ' ') : message.SetStartPadding('\n', 2));
			message = message.SetEndPadding('\n', 2);
			return message;
		}

		public static string SetEndPadding(this string text, char character, int minPadding)
		{
			string text2 = text;
			int num = 0;
			int num2 = text.Length - 1;
			while (num2 >= 0 && text[num2] == character)
			{
				num++;
				num2--;
			}
			int num3 = minPadding - num;
			if (num3 > 0)
			{
				text2 += new string(character, num3);
			}
			return text2;
		}

		public static string SetStartPadding(this string text, char character, int minPadding)
		{
			string text2 = text;
			int num = 0;
			for (int i = 0; i < text.Length && text[i] == character; i++)
			{
				num++;
			}
			int num2 = minPadding - num;
			if (num2 > 0)
			{
				text2 = new string(character, num2) + text2;
			}
			return text2;
		}
	}
}
namespace LethalAPI.LibTerminal.Models.Enums
{
	public enum AllowedCaller
	{
		None = -1,
		Player,
		Host
	}
	public enum SyncedTerminalClip
	{
		ItemPurchased,
		Error,
		BroadcastEffect
	}
}
namespace LethalAPI.LibTerminal.Interfaces
{
	public interface ITerminalInteraction
	{
		TerminalNode Prompt { get; }

		ServiceCollection Services { get; }

		object HandleTerminalResponse(ArgumentStream arguments);
	}
	public interface ITerminalInterface
	{
		bool APITextPostProcessing { get; }

		bool VanillaTextPostProcessing { get; }

		TerminalNode HandleInput(Terminal instance, ArgumentStream arguments);

		string PreProcessText(Terminal instance, string text);

		string PostProcessText(Terminal terminal, string text);

		TerminalNode GetSplashScreen(Terminal terminal);
	}
}
namespace LethalAPI.LibTerminal.Interactions
{
	public class ConfirmInteraction : ITerminalInteraction
	{
		public TerminalNode Prompt { get; private set; }

		public ServiceCollection Services { get; } = new ServiceCollection();


		public Delegate ConfirmHandler { get; set; }

		public Delegate DenyHandler { get; set; }

		public ConfirmInteraction()
		{
		}

		public ConfirmInteraction(TerminalNode prompt)
		{
			Prompt = prompt;
			PostprocessPrompt();
		}

		public ConfirmInteraction(Action<TerminalNode> promptBuilder)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			promptBuilder(val);
			WithPrompt(val);
		}

		public ConfirmInteraction(TerminalNode prompt, Delegate confirm, Delegate deny)
		{
			WithPrompt(prompt);
			ConfirmHandler = confirm;
			DenyHandler = deny;
		}

		public ConfirmInteraction(Action<TerminalNode> promptBuilder, Delegate confirm, Delegate deny)
		{
			WithPrompt(promptBuilder);
			ConfirmHandler = confirm;
			DenyHandler = deny;
		}

		public ConfirmInteraction(string prompt)
		{
			WithPrompt(prompt);
		}

		public ConfirmInteraction(string prompt, Delegate confirm, Delegate deny)
		{
			WithPrompt(prompt);
			ConfirmHandler = confirm;
			DenyHandler = deny;
		}

		public ConfirmInteraction WithPrompt(string prompt)
		{
			Prompt = ScriptableObject.CreateInstance<TerminalNode>();
			Prompt.WithDisplayText(prompt);
			PostprocessPrompt();
			return this;
		}

		public ConfirmInteraction WithPrompt(TerminalNode prompt)
		{
			Prompt = prompt;
			PostprocessPrompt();
			return this;
		}

		public ConfirmInteraction WithPrompt(Action<TerminalNode> promptBuilder)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			promptBuilder(val);
			WithPrompt(val);
			return this;
		}

		public ConfirmInteraction Confirm(Delegate confirmHandler)
		{
			ConfirmHandler = confirmHandler;
			return this;
		}

		public ConfirmInteraction Deny(Delegate denyHandler)
		{
			DenyHandler = denyHandler;
			return this;
		}

		public ConfirmInteraction WithContext(params object[] services)
		{
			Services.WithServices(services);
			return this;
		}

		public object HandleTerminalResponse(ArgumentStream arguments)
		{
			if (!arguments.TryReadNext(out string value))
			{
				return Deny(arguments);
			}
			if (value.Trim().Equals("confirm", StringComparison.InvariantCultureIgnoreCase))
			{
				return Confirm(arguments);
			}
			return Deny(arguments);
		}

		private object Confirm(ArgumentStream arguments)
		{
			if ((object)DenyHandler == null)
			{
				return string.Empty;
			}
			if (CommandActivator.TryCreateInvoker(arguments, Services, ConfirmHandler.GetMethodInfo(), out var invoker))
			{
				return invoker(ConfirmHandler.Target);
			}
			return null;
		}

		private object Deny(ArgumentStream arguments)
		{
			if ((object)DenyHandler == null)
			{
				return string.Empty;
			}
			if (CommandActivator.TryCreateInvoker(arguments, Services, DenyHandler.GetMethodInfo(), out var invoker))
			{
				return invoker(DenyHandler.Target);
			}
			return null;
		}

		private void PostprocessPrompt()
		{
			string text = Prompt.displayText ?? string.Empty;
			text = text.SetEndPadding('\n', 2) + "Please CONFIRM or DENY.\n";
			Prompt.displayText = text;
		}
	}
	public class TerminalInteraction : ITerminalInteraction
	{
		public TerminalNode Prompt { get; private set; }

		public ServiceCollection Services { get; } = new ServiceCollection();


		public List<Delegate> Handlers { get; } = new List<Delegate>();


		public TerminalInteraction()
		{
		}

		public TerminalInteraction(TerminalNode prompt, Delegate handler)
		{
			Prompt = prompt;
			Handlers.Add(handler);
		}

		public TerminalInteraction(Action<TerminalNode> promptBuilder, Delegate handler)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			promptBuilder(val);
			WithPrompt(val);
			Handlers.Add(handler);
		}

		public TerminalInteraction WithContext(params object[] services)
		{
			Services.WithServices(services);
			return this;
		}

		public TerminalInteraction WithPrompt(TerminalNode prompt)
		{
			Prompt = prompt;
			return this;
		}

		public TerminalInteraction WithPrompt(Action<TerminalNode> promptBuilder)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			promptBuilder(val);
			WithPrompt(val);
			return this;
		}

		public TerminalInteraction WithPrompt(string prompt)
		{
			Prompt = ScriptableObject.CreateInstance<TerminalNode>();
			Prompt.WithDisplayText(prompt);
			return this;
		}

		public TerminalInteraction WithHandler(Delegate handler)
		{
			Handlers.Add(handler);
			return this;
		}

		public object HandleTerminalResponse(ArgumentStream arguments)
		{
			List<(MethodInfo, object)> list = (from x in Handlers
				select (x.GetMethodInfo(), x.Target) into x
				orderby x.info.GetParameters().Length descending
				select x).ToList();
			foreach (Delegate handler in Handlers)
			{
				MethodInfo methodInfo = handler.GetMethodInfo();
				arguments.Reset();
				if (CommandActivator.TryCreateInvoker(arguments, Services, methodInfo, out var invoker))
				{
					object obj = invoker(handler.Target);
					if (obj != null)
					{
						return obj;
					}
				}
			}
			return null;
		}
	}
}
namespace LethalAPI.LibTerminal.Commands
{
	public class CommandInfoCommands
	{
		[TerminalCommand("Other", true)]
		public string CommandList()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Other commands:");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">VIEW MONITOR");
			stringBuilder.AppendLine("To toggle on/off the main monitor's map cam");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">SWITCH {RADAR}");
			stringBuilder.AppendLine("To switch the player view on the main monitor");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">PING [Radar booster name]");
			stringBuilder.AppendLine("To switch the player view on the main monitor");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">SCAN");
			stringBuilder.AppendLine("To scan for the number of items left on the current planet");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(">TRANSMIT [message]");
			stringBuilder.AppendLine("Transmit a message with the signal translator");
			stringBuilder.AppendLine();
			foreach (TerminalCommand item in TerminalRegistry.EnumerateCommands())
			{
				if (item.Description != null && item.CheckAllowed())
				{
					stringBuilder.AppendLine(">" + item.Name.ToUpper() + " " + item.Syntax?.ToUpper());
					stringBuilder.AppendLine(item.Description);
					stringBuilder.AppendLine();
				}
			}
			return stringBuilder.ToString();
		}

		[TerminalCommand("Help", false)]
		[CommandInfo("Shows further information about a command", "[Command]")]
		public string HelpCommand(string name)
		{
			StringBuilder stringBuilder = new StringBuilder();
			TerminalCommand[] array = TerminalRegistry.EnumerateCommands(name).ToArray();
			if (array.Length == 0)
			{
				return "Unknown command: '" + name + "'";
			}
			TerminalCommand[] array2 = array;
			foreach (TerminalCommand terminalCommand in array2)
			{
				stringBuilder.AppendLine(">" + terminalCommand.Name.ToUpper() + " " + terminalCommand.Syntax?.ToUpper());
				stringBuilder.AppendLine(terminalCommand.Description);
				if (!terminalCommand.CheckAllowed())
				{
					stringBuilder.AppendLine("[Host Only]");
				}
				stringBuilder.AppendLine();
			}
			return stringBuilder.ToString();
		}
	}
}
namespace LethalAPI.LibTerminal.Attributes
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
	public abstract class AccessControlAttribute : Attribute
	{
		public abstract bool CheckAllowed();
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
	public class AllowedCallerAttribute : AccessControlAttribute
	{
		public AllowedCaller Caller { get; }

		public AllowedCallerAttribute(AllowedCaller caller)
		{
			Caller = caller;
		}

		public override bool CheckAllowed()
		{
			switch (Caller)
			{
			case AllowedCaller.None:
				return false;
			case AllowedCaller.Player:
				return true;
			case AllowedCaller.Host:
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return false;
				}
				return ((NetworkBehaviour)StartOfRound.Instance).IsHost;
			default:
				return true;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
	public class CommandInfoAttribute : Attribute
	{
		public string Syntax { get; }

		public string Description { get; }

		public CommandInfoAttribute(string description, string syntax = "")
		{
			Syntax = syntax;
			Description = description;
		}
	}
	public sealed class CommandPriority : Attribute
	{
		public int Priority { get; }

		public CommandPriority(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	public sealed class RemainingTextAttribute : Attribute
	{
	}
	public class RequireInterfaceAttribute : AccessControlAttribute
	{
		public Type InterfaceType { get; }

		public RequireInterfaceAttribute(Type interfaceType)
		{
			InterfaceType = interfaceType;
		}

		public override bool CheckAllowed()
		{
			return CommandHandler.CurrentInterface != null && CommandHandler.CurrentInterface.GetType() == InterfaceType;
		}
	}
	public sealed class RequireInterfaceAttribute<T> : RequireInterfaceAttribute where T : ITerminalInterface
	{
		public RequireInterfaceAttribute()
			: base(typeof(T))
		{
		}
	}
	public sealed class StringConverterAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
	public class TerminalCommandAttribute : Attribute
	{
		public string CommandName { get; }

		public bool ClearText { get; }

		public TerminalCommandAttribute(string name, bool clearText = false)
		{
			CommandName = name;
			ClearText = clearText;
		}
	}
}

LethalCompanyInputUtils/LethalCompanyInputUtils.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalCompanyInputUtils.Data;
using LethalCompanyInputUtils.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("LethalCompanyInputUtils")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9e95a88c49ab86635dbebf33cfb26802052a8769")]
[assembly: AssemblyProduct("LethalCompanyInputUtils")]
[assembly: AssemblyTitle("LethalCompanyInputUtils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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 LethalCompanyInputUtils
{
	public static class LcInputActionApi
	{
		private static readonly Dictionary<string, LcInputActions> InputActionsMap = new Dictionary<string, LcInputActions>();

		private static IReadOnlyCollection<LcInputActions> InputActions => InputActionsMap.Values;

		internal static void LoadIntoUI(KepRemapPanel panel)
		{
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00d9: 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)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			UpdateFontScaling(panel);
			AdjustSizeAndPos(panel);
			LayoutElement val = EnsureLayoutElement(panel);
			val.minHeight = 0f;
			List<RemappableKey> remappableKeys = panel.remappableKeys;
			int num = remappableKeys.Count((RemappableKey key) => !key.gamepadOnly);
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Loaded)
				{
					continue;
				}
				foreach (InputActionReference actionRef in inputAction.ActionRefs)
				{
					InputBinding val2 = ((IEnumerable<InputBinding>)(object)actionRef.action.bindings).First();
					string name = ((InputBinding)(ref val2)).name;
					RemappableKey item = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						gamepadOnly = false
					};
					remappableKeys.Insert(num++, item);
					RemappableKey item2 = new RemappableKey
					{
						ControlName = name,
						currentInput = actionRef,
						rebindingIndex = 1,
						gamepadOnly = true
					};
					remappableKeys.Add(item2);
				}
				inputAction.Loaded = true;
			}
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
			val.minHeight += (panel.maxVertical + 1f) * panel.verticalOffset;
		}

		private static void UpdateFontScaling(KepRemapPanel panel)
		{
			TextMeshProUGUI component = ((Component)panel.keyRemapSlotPrefab.transform.Find("Text (1)")).GetComponent<TextMeshProUGUI>();
			if (!((TMP_Text)component).enableAutoSizing)
			{
				((TMP_Text)component).fontSizeMax = ((TMP_Text)component).fontSize;
				((TMP_Text)component).fontSizeMin = ((TMP_Text)component).fontSize - 4f;
				((TMP_Text)component).enableAutoSizing = true;
			}
		}

		private static void AdjustSizeAndPos(KepRemapPanel panel)
		{
			GameObject gameObject = ((Component)((Transform)panel.keyRemapContainer).parent).gameObject;
			if (gameObject.GetComponent<ContentSizeFitter>() == null)
			{
				panel.keyRemapContainer.SetPivotY(1f);
				panel.keyRemapContainer.SetAnchorMinY(1f);
				panel.keyRemapContainer.SetAnchorMaxY(1f);
				panel.keyRemapContainer.SetAnchoredPosY(0f);
				panel.keyRemapContainer.SetLocalPosY(0f);
				ContentSizeFitter obj = gameObject.AddComponent<ContentSizeFitter>();
				obj.horizontalFit = (FitMode)0;
				obj.verticalFit = (FitMode)1;
			}
		}

		private static LayoutElement EnsureLayoutElement(KepRemapPanel panel)
		{
			GameObject gameObject = ((Component)((Transform)panel.keyRemapContainer).parent).gameObject;
			LayoutElement component = gameObject.GetComponent<LayoutElement>();
			if (component != null)
			{
				return component;
			}
			return gameObject.AddComponent<LayoutElement>();
		}

		internal static void CalculateVerticalMaxForGamepad(KepRemapPanel panel)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			int num = panel.remappableKeys.Count((RemappableKey key) => key.gamepadOnly);
			float horizontalOffset = panel.horizontalOffset;
			Rect rect = ((Component)((Transform)panel.keyRemapContainer).parent).GetComponent<RectTransform>().rect;
			float num2 = Mathf.Floor(((Rect)(ref rect)).width / horizontalOffset);
			panel.maxVertical = (float)num / num2;
			LayoutElement obj = EnsureLayoutElement(panel);
			obj.minHeight += (panel.maxVertical + 3f) * panel.verticalOffset;
		}

		internal static void ResetLoadedInputActions()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Loaded = false;
			}
		}

		internal static void RegisterInputActions(LcInputActions lcInputActions, InputActionMapBuilder builder)
		{
			if (!InputActionsMap.TryAdd(lcInputActions.Id, lcInputActions))
			{
				Logging.Logger.LogWarning((object)("The mod [" + lcInputActions.Plugin.GUID + "] instantiated an Actions class [" + lcInputActions.GetType().Name + "] more than once!\n\t These classes should be treated as singletons!, do not instantiate more than once!"));
			}
			else
			{
				lcInputActions.CreateInputActions(in builder);
				InputActionSetupExtensions.AddActionMap(lcInputActions.GetAsset(), builder.Build());
				lcInputActions.GetAsset().Enable();
				lcInputActions.OnAssetLoaded();
				lcInputActions.Load();
				lcInputActions.BuildActionRefs();
			}
		}

		internal static void DisableForRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.Enabled)
				{
					inputAction.Disable();
				}
			}
		}

		internal static void ReEnableFromRebind()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				if (inputAction.WasEnabled)
				{
					inputAction.Enable();
				}
			}
		}

		internal static void SaveOverrides()
		{
			foreach (LcInputActions inputAction in InputActions)
			{
				inputAction.Save();
			}
		}
	}
	[BepInPlugin("com.rune580.LethalCompanyInputUtils", "Lethal Company Input Utils", "0.4.4")]
	public class LethalCompanyInputUtilsPlugin : BaseUnityPlugin
	{
		public const string ModId = "com.rune580.LethalCompanyInputUtils";

		public const string ModName = "Lethal Company Input Utils";

		public const string ModVersion = "0.4.4";

		private Harmony? _harmony;

		private void Awake()
		{
			Logging.SetLogSource(((BaseUnityPlugin)this).Logger);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.rune580.LethalCompanyInputUtils");
			SceneManager.activeSceneChanged += OnSceneChanged;
			FsUtils.EnsureControlsDir();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.rune580.LethalCompanyInputUtils is loaded!");
		}

		private static void OnSceneChanged(Scene current, Scene next)
		{
			LcInputActionApi.ResetLoadedInputActions();
		}
	}
}
namespace LethalCompanyInputUtils.Utils
{
	internal static class AssemblyUtils
	{
		public static BepInPlugin? GetBepInPlugin(this Assembly assembly)
		{
			foreach (Type validType in assembly.GetValidTypes())
			{
				BepInPlugin customAttribute = ((MemberInfo)validType).GetCustomAttribute<BepInPlugin>();
				if (customAttribute != null)
				{
					return customAttribute;
				}
			}
			return null;
		}

		public static IEnumerable<Type> GetValidTypes(this Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type type) => (object)type != null);
			}
		}
	}
	internal static class FsUtils
	{
		public static string SaveDir { get; } = GetSaveDir();


		public static string Pre041ControlsDir { get; } = Path.Combine(Paths.BepInExRootPath, "controls");


		public static string ControlsDir { get; } = Path.Combine(Paths.ConfigPath, "controls");


		private static string GetSaveDir()
		{
			string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
			return Path.Combine(folderPath, "AppData", "LocalLow", "ZeekerssRBLX", "Lethal Company");
		}

		public static void EnsureControlsDir()
		{
			if (!Directory.Exists(ControlsDir))
			{
				Directory.CreateDirectory(ControlsDir);
			}
		}
	}
	internal static class Logging
	{
		private static ManualLogSource? _logSource;

		internal static ManualLogSource Logger { get; } = _logSource;


		internal static void SetLogSource(ManualLogSource logSource)
		{
			_logSource = logSource;
		}
	}
	internal static class RuntimeHelper
	{
		public static void SetLocalPosY(this RectTransform rectTransform, float y)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = ((Transform)rectTransform).localPosition;
			((Transform)rectTransform).localPosition = new Vector3(localPosition.x, y, localPosition.z);
		}

		public static void SetPivotY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.pivot = new Vector2(rectTransform.pivot.x, y);
		}

		public static void SetAnchorMinY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchorMin = new Vector2(rectTransform.anchorMin.x, y);
		}

		public static void SetAnchorMaxY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchorMax = new Vector2(rectTransform.anchorMax.x, y);
		}

		public static void SetAnchoredPosY(this RectTransform rectTransform, float y)
		{
			//IL_0002: 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)
			rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, y);
		}
	}
}
namespace LethalCompanyInputUtils.Patches
{
	public static class InputControlPathPatches
	{
		[HarmonyPatch]
		public static class ToHumanReadableStringPatch
		{
			public static IEnumerable<MethodBase> TargetMethods()
			{
				return from method in AccessTools.GetDeclaredMethods(typeof(InputControlPath))
					where method.Name == "ToHumanReadableString" && method.ReturnType == typeof(string)
					select method;
			}

			public static void Postfix(ref string __result)
			{
				string text = __result;
				if ((text == "<InputUtils-Gamepad-Not-Bound>" || text == "<InputUtils-Kbm-Not-Bound>") ? true : false)
				{
					__result = "";
				}
			}
		}
	}
	public static class KeyRemapPanelPatches
	{
		[HarmonyPatch(typeof(KepRemapPanel), "LoadKeybindsUI")]
		public static class LoadKeybindsUIPatch
		{
			public static void Prefix(KepRemapPanel __instance)
			{
				LcInputActionApi.DisableForRebind();
				LcInputActionApi.LoadIntoUI(__instance);
			}

			public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Expected O, but got Unknown
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Expected O, but got Unknown
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Expected O, but got Unknown
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Expected O, but got Unknown
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				FieldInfo maxVerticalField = AccessTools.Field(typeof(KepRemapPanel), "maxVertical");
				val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsLdarg(code, (int?)0)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.LoadsField(code, maxVerticalField, false)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Ldc_R4 && (float)code.operand == 2f), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Add), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => code.opcode == OpCodes.Conv_I4), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction code) => CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null)), (string)null)
				});
				val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LcInputActionApi), "CalculateVerticalMaxForGamepad", new Type[1] { typeof(KepRemapPanel) }, (Type[])null))
				});
				return val.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(KepRemapPanel), "UnloadKeybindsUI")]
		public static class UnloadKeybindsUIPatch
		{
			public static void Prefix()
			{
				LcInputActionApi.SaveOverrides();
				LcInputActionApi.ReEnableFromRebind();
			}
		}
	}
}
namespace LethalCompanyInputUtils.Data
{
	[Serializable]
	public struct BindingOverride
	{
		public string? action;

		public string? origPath;

		public string? path;
	}
	[Serializable]
	public class BindingOverrides
	{
		public List<BindingOverride> overrides;

		private BindingOverrides()
		{
			overrides = new List<BindingOverride>();
		}

		public BindingOverrides(IEnumerable<InputBinding> bindings)
		{
			//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)
			overrides = new List<BindingOverride>();
			foreach (InputBinding binding in bindings)
			{
				InputBinding current = binding;
				if (((InputBinding)(ref current)).hasOverrides)
				{
					BindingOverride item = new BindingOverride
					{
						action = ((InputBinding)(ref current)).action,
						origPath = ((InputBinding)(ref current)).path,
						path = ((InputBinding)(ref current)).overridePath
					};
					overrides.Add(item);
				}
			}
		}

		public void LoadInto(InputActionAsset asset)
		{
			foreach (BindingOverride @override in overrides)
			{
				InputAction obj = asset.FindAction(@override.action, false);
				if (obj != null)
				{
					InputActionRebindingExtensions.ApplyBindingOverride(obj, @override.path, (string)null, @override.origPath);
				}
			}
		}

		public static BindingOverrides FromJson(string json)
		{
			BindingOverrides bindingOverrides = new BindingOverrides();
			JToken value = JsonConvert.DeserializeObject<JObject>(json).GetValue("overrides");
			bindingOverrides.overrides = value.ToObject<List<BindingOverride>>();
			return bindingOverrides;
		}
	}
}
namespace LethalCompanyInputUtils.Api
{
	[AttributeUsage(AttributeTargets.Property)]
	public class InputActionAttribute : Attribute
	{
		public readonly string KbmPath;

		public string? ActionId { get; set; }

		public string? GamepadPath { get; set; }

		public InputActionType ActionType { get; set; } = (InputActionType)1;


		public string? KbmInteractions { get; set; }

		public string? GamepadInteractions { get; set; }

		public string? Name { get; set; }

		[Obsolete("Prefer using the named optional params instead.")]
		public InputActionAttribute(string action, string kbmPath, string gamepadPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ActionId = action;
			KbmPath = kbmPath;
			GamepadPath = gamepadPath;
		}

		public InputActionAttribute(string kbmPath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			KbmPath = kbmPath;
		}
	}
	public class InputActionBindingBuilder
	{
		private readonly InputActionMapBuilder _mapBuilder;

		private string? _actionId;

		private string? _kbmPath;

		private string? _gamepadPath;

		private string? _kbmInteractions;

		private string? _gamepadInteractions;

		private InputActionType _actionType;

		private string? _name;

		internal InputActionBindingBuilder(InputActionMapBuilder mapBuilder)
		{
			_mapBuilder = mapBuilder;
		}

		public InputActionBindingBuilder WithActionId(string actionId)
		{
			_actionId = actionId;
			return this;
		}

		public InputActionBindingBuilder WithKbmPath(string kbmPath)
		{
			_kbmPath = kbmPath;
			return this;
		}

		public InputActionBindingBuilder WithGamepadPath(string gamepadPath)
		{
			_gamepadPath = gamepadPath;
			return this;
		}

		public InputActionBindingBuilder WithKbmInteractions(string? kbmInteractions)
		{
			_kbmInteractions = kbmInteractions;
			return this;
		}

		public InputActionBindingBuilder WithGamepadInteractions(string? gamepadInteractions)
		{
			_gamepadInteractions = gamepadInteractions;
			return this;
		}

		public InputActionBindingBuilder WithActionType(InputActionType actionType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_actionType = actionType;
			return this;
		}

		public InputActionBindingBuilder WithBindingName(string? name)
		{
			_name = name;
			return this;
		}

		public InputAction Finish()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (_name == null)
			{
				_name = _actionId;
			}
			InputAction val = new InputAction(_actionId, _actionType, (string)null, (string)null, (string)null, (string)null);
			_mapBuilder.WithAction(val);
			if (_kbmPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_kbmPath, _actionId, (string)null, (string)null, _kbmInteractions, _name));
			}
			if (_gamepadPath != null)
			{
				_mapBuilder.WithBinding(new InputBinding(_gamepadPath, _actionId, (string)null, (string)null, _gamepadInteractions, _name));
			}
			return val;
		}
	}
	public class InputActionMapBuilder
	{
		private readonly InputActionMap _actionMap = new InputActionMap(mapName);

		public InputActionMapBuilder(string mapName)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown


		public InputActionMapBuilder WithAction(InputAction action)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddAction(_actionMap, action.name, action.type, (string)null, (string)null, (string)null, (string)null, (string)null);
			return this;
		}

		public InputActionMapBuilder WithBinding(InputBinding binding)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			InputActionSetupExtensions.AddBinding(_actionMap, binding);
			return this;
		}

		public InputActionBindingBuilder NewActionBinding()
		{
			return new InputActionBindingBuilder(this);
		}

		internal InputActionMap Build()
		{
			return _actionMap;
		}
	}
	public abstract class LcInputActions
	{
		public const string UnboundKeyboardAndMouseIdentifier = "<InputUtils-Kbm-Not-Bound>";

		public const string UnboundGamepadIdentifier = "<InputUtils-Gamepad-Not-Bound>";

		private readonly string _jsonPath;

		private readonly List<InputActionReference> _actionRefs = new List<InputActionReference>();

		internal bool Loaded;

		private readonly Dictionary<PropertyInfo, InputActionAttribute> _inputProps;

		public InputActionAsset Asset { get; }

		internal bool WasEnabled { get; private set; }

		public bool Enabled => Asset.enabled;

		internal IReadOnlyCollection<InputActionReference> ActionRefs => _actionRefs;

		internal string Id => Plugin.GUID + "." + MapName;

		public BepInPlugin Plugin { get; }

		protected virtual string MapName => GetType().Name;

		internal InputActionAsset GetAsset()
		{
			return Asset;
		}

		protected LcInputActions()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			Asset = ScriptableObject.CreateInstance<InputActionAsset>();
			Plugin = Assembly.GetCallingAssembly().GetBepInPlugin() ?? throw new InvalidOperationException();
			_jsonPath = Path.Combine(FsUtils.ControlsDir, Id + ".json");
			InputActionMapBuilder inputActionMapBuilder = new InputActionMapBuilder(Id);
			PropertyInfo[] properties = GetType().GetProperties();
			_inputProps = new Dictionary<PropertyInfo, InputActionAttribute>();
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				InputActionAttribute customAttribute = propertyInfo.GetCustomAttribute<InputActionAttribute>();
				if (customAttribute != null && !(propertyInfo.PropertyType != typeof(InputAction)))
				{
					InputActionAttribute inputActionAttribute = customAttribute;
					if (inputActionAttribute.ActionId == null)
					{
						string text = (inputActionAttribute.ActionId = propertyInfo.Name);
					}
					inputActionAttribute = customAttribute;
					if (inputActionAttribute.GamepadPath == null)
					{
						string text = (inputActionAttribute.GamepadPath = "<InputUtils-Gamepad-Not-Bound>");
					}
					string kbmPath = (string.IsNullOrEmpty(customAttribute.KbmPath) ? "<InputUtils-Kbm-Not-Bound>" : customAttribute.KbmPath);
					inputActionMapBuilder.NewActionBinding().WithActionId(customAttribute.ActionId).WithActionType(customAttribute.ActionType)
						.WithBindingName(customAttribute.Name)
						.WithKbmPath(kbmPath)
						.WithGamepadPath(customAttribute.GamepadPath)
						.WithKbmInteractions(customAttribute.KbmInteractions)
						.WithGamepadInteractions(customAttribute.GamepadInteractions)
						.Finish();
					_inputProps[propertyInfo] = customAttribute;
				}
			}
			LcInputActionApi.RegisterInputActions(this, inputActionMapBuilder);
		}

		public virtual void CreateInputActions(in InputActionMapBuilder builder)
		{
		}

		public virtual void OnAssetLoaded()
		{
		}

		internal void BuildActionRefs()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<PropertyInfo, InputActionAttribute> inputProp in _inputProps)
			{
				inputProp.Deconstruct(out var key, out var value);
				PropertyInfo propertyInfo = key;
				InputActionAttribute inputActionAttribute = value;
				InputAction value2 = Asset.FindAction(inputActionAttribute.ActionId, false);
				propertyInfo.SetValue(this, value2);
			}
			IEnumerable<InputActionReference> collection = ((IEnumerable<InputActionMap>)(object)Asset.actionMaps).SelectMany((InputActionMap map) => (IEnumerable<InputAction>)(object)map.actions).Select((Func<InputAction, InputActionReference>)InputActionReference.Create);
			_actionRefs.AddRange(collection);
		}

		public void Enable()
		{
			WasEnabled = Asset.enabled;
			Asset.Enable();
		}

		public void Disable()
		{
			WasEnabled = Asset.enabled;
			Asset.Disable();
		}

		internal void Save()
		{
			BindingOverrides bindingOverrides = new BindingOverrides(Asset.bindings);
			File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides));
		}

		internal void Load()
		{
			try
			{
				ApplyMigrations();
			}
			catch (Exception ex)
			{
				Logging.Logger.LogError((object)"Got error when applying migrations, skipping...");
				Logging.Logger.LogError((object)ex);
			}
			if (!File.Exists(_jsonPath))
			{
				return;
			}
			try
			{
				BindingOverrides.FromJson(File.ReadAllText(_jsonPath)).LoadInto(Asset);
			}
			catch (Exception ex2)
			{
				Logging.Logger.LogError((object)ex2);
			}
		}

		private void ApplyMigrations()
		{
			string text = Path.Combine(FsUtils.Pre041ControlsDir, Id + ".json");
			if (File.Exists(text) && !File.Exists(_jsonPath))
			{
				File.Move(text, _jsonPath);
			}
			if (!File.Exists(_jsonPath) || !File.ReadAllText(_jsonPath).Replace(" ", "").Contains("\"origPath\":\"\""))
			{
				return;
			}
			BindingOverrides bindingOverrides = BindingOverrides.FromJson(File.ReadAllText(_jsonPath));
			for (int i = 0; i < bindingOverrides.overrides.Count; i++)
			{
				BindingOverride value = bindingOverrides.overrides[i];
				if (string.IsNullOrEmpty(value.origPath) && value.path != null)
				{
					if (value.path.StartsWith("<Keyboard>") || value.path.StartsWith("<Mouse>"))
					{
						value.origPath = "<InputUtils-Kbm-Not-Bound>";
					}
					else
					{
						value.origPath = "<InputUtils-Gamepad-Not-Bound>";
					}
					bindingOverrides.overrides[i] = value;
				}
			}
			File.WriteAllText(_jsonPath, JsonConvert.SerializeObject((object)bindingOverrides));
		}
	}
}