Decompiled source of Economy Rebalance v0.6.1

0Harmony.dll

Decompiled 2 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.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
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: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[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.10.2.0")]
[assembly: AssemblyInformationalVersion("2.10.2")]
[assembly: AssemblyProduct("HarmonyX")]
[assembly: AssemblyTitle("0Harmony")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.10.2.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 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>)val.Generate().CreateDelegate(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>)obj.Generate().CreateDelegate(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>)obj.Generate().CreateDelegate(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>)obj.Generate().CreateDelegate(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>)obj.Generate().CreateDelegate(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 (methodInfo.ReturnType == typeof(void))
			{
				Emit(iLGenerator, OpCodes.Ldnull);
			}
			else
			{
				EmitBoxIfNeeded(iLGenerator, methodInfo.ReturnType);
			}
			Emit(iLGenerator, OpCodes.Ret);
			return (FastInvokeHandler)val.Generate().CreateDelegate(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_0162: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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");
			}
			if (!standin.method.IsStatic)
			{
				throw new ArgumentException("standin", "standin.method is not static");
			}
			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 || m.GetDeclaringType() != null)
				{
					return m.methodName != null;
				}
				return false;
			}
			static bool Same(HarmonyMethod m1, HarmonyMethod m2)
			{
				if (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 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 && 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)
		{
			return AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), 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 typeName, string methodName)
		{
			info.declaringType = AccessTools.TypeByName(typeName);
			info.methodName = methodName;
		}

		public HarmonyPatch(string typeName, string methodName, MethodType methodType, Type[] argumentTypes = null, ArgumentType[] argumentVariations = null)
		{
			info.declaringType = AccessTools.TypeByName(typeName);
			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);
		}

		public HarmonyPatch(string typeName, string methodName, MethodType methodType = MethodType.Normal)
		{
			info.declaringType = AccessTools.TypeByName(typeName);
			info.methodName = methodName;
			info.methodType = methodType;
		}

		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 (type == typeof(Label))
			{
				return $"Label{((Label)argument).GetHashCode()}";
			}
			if (type == typeof(Label[]))
			{
				return "Labels" + string.Join(",", ((Label[])argument).Select((Label l) => l.GetHashCode().ToString()).ToArray());
			}
			if (type == typeof(LocalBuilder))
			{
				return $"{((LocalBuilder)argument).LocalIndex} ({((LocalBuilder)argument).LocalType})";
			}
			if (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 = "*")
		{
			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 (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 MethodBase GetOriginalMethodFromStackframe(StackFrame frame)
		{
			MethodBase methodBase = GetMethodFromStackframe(frame);
			if (methodBase is MethodInfo replacement)
			{
				methodBase = GetOriginalMethod(replacement) ?? methodBase;
			}
			return methodBase;
		}

		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 = new Dictionary<int, CodeInstruction>();

		private int errorOffset = -1;

		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)
		{
			if (ex is HarmonyException ex2)
			{
				Dictionary<int, CodeInstruction> dictionary = ex2.instructions;
				if (dictionary != null && dictionary.Count > 0 && ex2.errorOffset >= 0)
				{
					return ex;
				}
			}
			Match match = Regex.Match(ex.Message.TrimEnd(Array.Empty<char>()), "(?:Reason: )?Invalid IL code in.+: IL_(\\d{4}): (.+)$");
			if (!match.Success)
			{
				return new HarmonyException("IL Compile Error (unknown location)", ex);
			}
			Dictionary<int, CodeInstruction> dictionary2 = 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 ex3)
			{
				if (dictionary2.Count != 0)
				{
					ex3.instructions = dictionary2;
					ex3.errorOffset = num;
				}
				return ex3;
			}
			return new HarmonyException(ex, dictionary2, 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;

		public HarmonyMethod()
		{
		}

		private void ImportMethod(MethodInfo theMethod)
		{
			if ((object)theMethod == null)
			{
				throw new ArgumentNullException("theMethod", "Harmony method is null (did you target a wrong or missing method?)");
			}
			if (!theMethod.IsStatic)
			{
				throw new ArgumentException("Harmony method must be static", "theMethod");
			}
			method = theMethod;
			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.FullDescription() : "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()
		{
			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) => p.PatchMethod != patch).ToArray();
			postfixes = postfixes.Where((Patch p) => p.PatchMethod != patch).ToArray();
			transpilers = transpilers.Where((Patch p) => p.PatchMethod != patch).ToArray();
			finalizers = finalizers.Where((Patch p) => p.PatchMethod != patch).ToArray();
			ilmanipulators = ilmanipulators.Where((Patch p) => 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 (methodInfo.ReturnType != typeof(DynamicMethod) && methodInfo.ReturnType != typeof(MethodInfo))
			{
				return methodInfo;
			}
			if (!methodInfo.IsStatic)
			{
				return methodInfo;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length != 1)
			{
				return methodInfo;
			}
			if (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 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, 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, Array.Empty<object>()))
			{
				RunMethod<HarmonyCleanup>(ref exception, Array.Empty<object>());
				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 targ

RealEco.dll

Decompiled 2 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 System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Colossal;
using Colossal.Collections;
using Colossal.Entities;
using Colossal.IO.AssetDatabase;
using Colossal.Localization;
using Colossal.Logging;
using Colossal.UI.Binding;
using Game;
using Game.Agents;
using Game.Areas;
using Game.Buildings;
using Game.Citizens;
using Game.City;
using Game.Common;
using Game.Companies;
using Game.Debug;
using Game.Economy;
using Game.Modding;
using Game.Net;
using Game.Objects;
using Game.Pathfind;
using Game.Prefabs;
using Game.Routes;
using Game.SceneFlow;
using Game.Simulation;
using Game.Tools;
using Game.UI;
using Game.UI.InGame;
using Game.Vehicles;
using Game.Zones;
using HarmonyLib;
using HookUILib.Core;
using Microsoft.CodeAnalysis;
using RealEco.Config;
using RealEco.Systems;
using Unity.Assertions;
using Unity.Burst;
using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Scripting;

[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("RealEco")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Economy Rebalance")]
[assembly: AssemblyFileVersion("0.6.1.0")]
[assembly: AssemblyInformationalVersion("0.6.1+8410fe10e333205eb84b8a8591474e45eaecf0e4")]
[assembly: AssemblyProduct("RealEco")]
[assembly: AssemblyTitle("RealEco")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.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 RealEco
{
	public class Mod : IMod
	{
		public static ILog log = LogManager.GetLogger("RealEco").SetShowsErrorsInUI(false);

		public void OnLoad(UpdateSystem updateSystem)
		{
			log.Info((object)"OnLoad");
			ExecutableAsset val = default(ExecutableAsset);
			if (GameManager.instance.modManager.TryGetExecutableAsset((IMod)(object)this, ref val))
			{
				log.Info((object)("Current mod asset at " + ((AssetData)val).path));
			}
			GameManager.instance.localizationManager.AddSource("en-US", (IDictionarySource)(object)new LocaleEN());
		}

		public void OnDispose()
		{
			log.Info((object)"OnDispose");
		}
	}
	[HarmonyPatch]
	public class CommercialDemandSystem_Patches
	{
		[BurstCompile]
		private struct UpdateCommercialDemandJob : IJob
		{
			[ReadOnly]
			public NativeList<ArchetypeChunk> m_FreePropertyChunks;

			[ReadOnly]
			public NativeList<ArchetypeChunk> m_CommercialProcessDataChunks;

			[ReadOnly]
			public EntityTypeHandle m_EntityType;

			[ReadOnly]
			public ComponentTypeHandle<PrefabRef> m_PrefabType;

			[ReadOnly]
			public ComponentTypeHandle<IndustrialProcessData> m_ProcessType;

			[ReadOnly]
			public BufferTypeHandle<Renter> m_RenterType;

			[ReadOnly]
			public ComponentLookup<BuildingPropertyData> m_BuildingPropertyDatas;

			[ReadOnly]
			public ComponentLookup<ResourceData> m_ResourceDatas;

			[ReadOnly]
			public ComponentLookup<WorkplaceData> m_WorkplaceDatas;

			[ReadOnly]
			public ComponentLookup<CommercialCompany> m_CommercialCompanies;

			[ReadOnly]
			public ComponentLookup<Population> m_Populations;

			[ReadOnly]
			public ComponentLookup<Tourism> m_Tourisms;

			[ReadOnly]
			public ResourcePrefabs m_ResourcePrefabs;

			public EconomyParameterData m_EconomyParameters;

			public DemandParameterData m_DemandParameters;

			[ReadOnly]
			public NativeArray<int> m_EmployableByEducation;

			[ReadOnly]
			public NativeArray<int> m_TaxRates;

			[ReadOnly]
			public NativeArray<int> m_FreeWorkplaces;

			public float m_BaseConsumptionSum;

			public Entity m_City;

			public NativeValue<int> m_CompanyDemand;

			public NativeValue<int> m_BuildingDemand;

			public NativeArray<int> m_DemandFactors;

			public NativeArray<int> m_Consumptions;

			public NativeArray<int> m_FreeProperties;

			public NativeArray<int> m_ResourceDemands;

			public NativeArray<int> m_BuildingDemands;

			[ReadOnly]
			public NativeArray<int> m_Productions;

			[ReadOnly]
			public NativeArray<int> m_TotalAvailables;

			[ReadOnly]
			public NativeArray<int> m_TotalMaximums;

			[ReadOnly]
			public NativeArray<int> m_Companies;

			[ReadOnly]
			public NativeArray<int> m_Propertyless;

			[ReadOnly]
			public NativeArray<int> m_TotalMaxWorkers;

			[ReadOnly]
			public NativeArray<int> m_TotalCurrentWorkers;

			public NativeArray<int> m_ActualConsumptions;

			public NativeArray<CommercialUISystem.DemandData> m_DemandData;

			public void Execute()
			{
				//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_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_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_002a: 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_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_0054: 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_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: 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_0136: 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_0145: 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_0277: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				//IL_016c: 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_0285: Unknown result type (might be due to invalid IL or missing references)
				//IL_0286: Unknown result type (might be due to invalid IL or missing references)
				//IL_029e: 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_02a4: 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_02bf: 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_02c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d1: 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_02dc: 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: 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_02fc: 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_0304: 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_01ce: 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_01d5: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: 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_01e7: 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)
				//IL_01ee: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0469: 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_0470: Unknown result type (might be due to invalid IL or missing references)
				//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0853: Unknown result type (might be due to invalid IL or missing references)
				//IL_0854: Unknown result type (might be due to invalid IL or missing references)
				//IL_085f: Invalid comparison between Unknown and I8
				//IL_0880: Unknown result type (might be due to invalid IL or missing references)
				//IL_0881: Unknown result type (might be due to invalid IL or missing references)
				//IL_088c: Invalid comparison between Unknown and I8
				ResourceIterator iterator = ResourceIterator.GetIterator();
				Population val = m_Populations[m_City];
				Tourism val2 = m_Tourisms[m_City];
				int num = (val.m_Population + val.m_PopulationWithMoveIn) / 2;
				while (((ResourceIterator)(ref iterator)).Next())
				{
					int resourceIndex = EconomyUtils.GetResourceIndex(iterator.resource);
					m_Consumptions[resourceIndex] = DemandUtils.EstimateResourceDemand(iterator.resource, ref m_EconomyParameters, num, val2.m_AverageTourists, m_ResourcePrefabs, m_ResourceDatas, m_BaseConsumptionSum) / 4;
					m_Consumptions[resourceIndex] = math.max(m_Consumptions[resourceIndex], m_ActualConsumptions[resourceIndex]);
					m_FreeProperties[resourceIndex] = 0;
				}
				ref NativeArray<int> consumptions = ref m_Consumptions;
				int resourceIndex2 = EconomyUtils.GetResourceIndex((Resource)1024);
				consumptions[resourceIndex2] += DemandUtils.EstimateVehicleExtraDemand(num);
				for (int i = 0; i < m_DemandFactors.Length; i++)
				{
					m_DemandFactors[i] = 0;
				}
				for (int j = 0; j < m_FreePropertyChunks.Length; j++)
				{
					ArchetypeChunk val3 = m_FreePropertyChunks[j];
					NativeArray<PrefabRef> nativeArray = ((ArchetypeChunk)(ref val3)).GetNativeArray<PrefabRef>(ref m_PrefabType);
					BufferAccessor<Renter> bufferAccessor = ((ArchetypeChunk)(ref val3)).GetBufferAccessor<Renter>(ref m_RenterType);
					for (int k = 0; k < nativeArray.Length; k++)
					{
						Entity prefab = nativeArray[k].m_Prefab;
						if (!m_BuildingPropertyDatas.HasComponent(prefab))
						{
							continue;
						}
						bool flag = false;
						DynamicBuffer<Renter> val4 = bufferAccessor[k];
						for (int l = 0; l < val4.Length; l++)
						{
							if (m_CommercialCompanies.HasComponent(val4[l].m_Renter))
							{
								flag = true;
								break;
							}
						}
						if (flag)
						{
							continue;
						}
						BuildingPropertyData val5 = m_BuildingPropertyDatas[prefab];
						ResourceIterator iterator2 = ResourceIterator.GetIterator();
						while (((ResourceIterator)(ref iterator2)).Next())
						{
							if ((val5.m_AllowedSold & iterator2.resource) != 0)
							{
								ref NativeArray<int> freeProperties = ref m_FreeProperties;
								resourceIndex2 = EconomyUtils.GetResourceIndex(iterator2.resource);
								int num2 = freeProperties[resourceIndex2];
								freeProperties[resourceIndex2] = num2 + 1;
							}
						}
					}
				}
				m_CompanyDemand.value = 0;
				bool flag2 = m_BuildingDemand.value > 0;
				m_BuildingDemand.value = 0;
				iterator = ResourceIterator.GetIterator();
				int num3 = 0;
				WorkplaceComplexity val6 = default(WorkplaceComplexity);
				while (((ResourceIterator)(ref iterator)).Next())
				{
					int resourceIndex3 = EconomyUtils.GetResourceIndex(iterator.resource);
					if (!m_ResourceDatas.HasComponent(((ResourcePrefabs)(ref m_ResourcePrefabs))[iterator.resource]))
					{
						continue;
					}
					_ = m_ResourceDatas[((ResourcePrefabs)(ref m_ResourcePrefabs))[iterator.resource]];
					if (!EconomyUtils.GetProcessComplexity(m_CommercialProcessDataChunks, m_WorkplaceDatas, iterator.resource, m_EntityType, m_ProcessType, ref val6))
					{
						continue;
					}
					Workplaces val7 = WorkProviderSystem.CalculateNumberOfWorkplaces(20, val6, 1);
					float num4 = 0f;
					for (int m = 0; m < 5; m++)
					{
						num4 = ((m >= 2) ? (num4 + math.min(5f * (float)((Workplaces)(ref val7))[m], (float)math.max(0, m_EmployableByEducation[m] - m_FreeWorkplaces[m]))) : (num4 + 5f * (float)((Workplaces)(ref val7))[m]));
					}
					float num5 = 0.4f * (num4 / 50f - 1f);
					float num6 = -9f + 10f * (((float)m_TotalCurrentWorkers[resourceIndex3] + 1f) / ((float)m_TotalMaxWorkers[resourceIndex3] + 1f));
					if (num6 > 0f)
					{
						num6 *= 0.5f;
					}
					float num7 = ((m_TotalMaximums[resourceIndex3] == 0) ? 0f : (-2.5f + 5f * (1f - (float)m_TotalAvailables[resourceIndex3] / (float)m_TotalMaximums[resourceIndex3])));
					float num8 = (m_DemandParameters.m_CommercialBaseDemand * (float)m_Consumptions[resourceIndex3] - (float)m_Productions[resourceIndex3]) / math.max(100f, (float)m_Consumptions[resourceIndex3] + 1f);
					float num9 = -0.2f * ((float)TaxSystem.GetCommercialTaxRate(iterator.resource, m_TaxRates) - 10f);
					m_ResourceDemands[resourceIndex3] = Mathf.RoundToInt(100f * (num7 + num6 + num5 + num9 + num8));
					CommercialUISystem.DemandData demandData = m_DemandData[resourceIndex3];
					demandData.Resource = iterator.resource;
					demandData.Demand = m_ResourceDemands[resourceIndex3];
					demandData.Building = m_BuildingDemands[resourceIndex3];
					demandData.Free = m_FreeProperties[resourceIndex3];
					demandData.Companies = m_Companies[resourceIndex3];
					demandData.Workers = m_TotalCurrentWorkers[resourceIndex3];
					demandData.SvcFactor = Mathf.RoundToInt(100f * num7);
					demandData.SvcPercent = ((m_TotalMaximums[resourceIndex3] != 0) ? (100 * m_TotalAvailables[resourceIndex3] / m_TotalMaximums[resourceIndex3]) : 0);
					demandData.CapFactor = Mathf.RoundToInt(100f * num8);
					demandData.CapPercent = 100 * m_Productions[resourceIndex3] / math.max(100, m_Consumptions[resourceIndex3]);
					demandData.CapPerCompany = ((m_Companies[resourceIndex3] != 0) ? (m_Productions[resourceIndex3] / m_Companies[resourceIndex3]) : 0);
					demandData.WrkFactor = Mathf.RoundToInt(100f * num6);
					demandData.WrkPercent = 100 * (m_TotalCurrentWorkers[resourceIndex3] + 1) / (m_TotalMaxWorkers[resourceIndex3] + 1);
					demandData.EduFactor = Mathf.RoundToInt(100f * num5);
					demandData.TaxFactor = Mathf.RoundToInt(100f * num9);
					m_DemandData[resourceIndex3] = demandData;
					int num10 = m_ResourceDemands[resourceIndex3];
					if (m_FreeProperties[resourceIndex3] == 0)
					{
						m_ResourceDemands[resourceIndex3] = 0;
					}
					if (m_Consumptions[resourceIndex3] > 0)
					{
						ref NativeValue<int> companyDemand = ref m_CompanyDemand;
						companyDemand.value += Mathf.RoundToInt((float)math.min(100, math.max(0, m_ResourceDemands[resourceIndex3])));
						m_BuildingDemands[resourceIndex3] = math.max(0, Mathf.CeilToInt(math.min(math.max(1f, (float)math.min(1, m_Propertyless[resourceIndex3]) + (float)m_Companies[resourceIndex3] / m_DemandParameters.m_FreeCommercialProportion) - (float)m_FreeProperties[resourceIndex3], (float)num10)));
						if (m_BuildingDemands[resourceIndex3] > 0)
						{
							ref NativeValue<int> buildingDemand = ref m_BuildingDemand;
							buildingDemand.value += ((m_BuildingDemands[resourceIndex3] > 0) ? num10 : 0);
						}
					}
					if (!flag2 || (m_BuildingDemands[resourceIndex3] > 0 && num10 > 0))
					{
						int num11 = ((m_BuildingDemands[resourceIndex3] > 0) ? num10 : 0);
						int demandFactorEffect = DemandUtils.GetDemandFactorEffect(m_ResourceDemands[resourceIndex3], num5);
						int demandFactorEffect2 = DemandUtils.GetDemandFactorEffect(m_ResourceDemands[resourceIndex3], num6);
						int num12 = DemandUtils.GetDemandFactorEffect(m_ResourceDemands[resourceIndex3], num8) + DemandUtils.GetDemandFactorEffect(m_ResourceDemands[resourceIndex3], num7);
						int demandFactorEffect3 = DemandUtils.GetDemandFactorEffect(m_ResourceDemands[resourceIndex3], num9);
						int num13 = demandFactorEffect + demandFactorEffect2 + num12 + demandFactorEffect3;
						consumptions = ref m_DemandFactors;
						consumptions[2] = consumptions[2] + demandFactorEffect;
						consumptions = ref m_DemandFactors;
						consumptions[1] = consumptions[1] + demandFactorEffect2;
						if ((long)iterator.resource == 2048)
						{
							consumptions = ref m_DemandFactors;
							consumptions[9] = consumptions[9] + num12;
						}
						else if ((long)iterator.resource == 65536)
						{
							consumptions = ref m_DemandFactors;
							consumptions[16] = consumptions[16] + num12;
						}
						else
						{
							consumptions = ref m_DemandFactors;
							consumptions[4] = consumptions[4] + num12;
						}
						consumptions = ref m_DemandFactors;
						consumptions[11] = consumptions[11] + demandFactorEffect3;
						consumptions = ref m_DemandFactors;
						consumptions[13] = consumptions[13] + math.min(0, num11 - num13);
					}
					num3++;
					m_ResourceDemands[resourceIndex3] = math.min(100, math.max(0, m_ResourceDemands[resourceIndex3]));
				}
				m_BuildingDemand.value = math.clamp(2 * m_BuildingDemand.value / num3, 0, 100);
			}
		}

		private struct TypeHandle
		{
			[ReadOnly]
			public EntityTypeHandle __Unity_Entities_Entity_TypeHandle;

			[ReadOnly]
			public ComponentTypeHandle<PrefabRef> __Game_Prefabs_PrefabRef_RO_ComponentTypeHandle;

			[ReadOnly]
			public ComponentTypeHandle<IndustrialProcessData> __Game_Prefabs_IndustrialProcessData_RO_ComponentTypeHandle;

			[ReadOnly]
			public BufferTypeHandle<Renter> __Game_Buildings_Renter_RO_BufferTypeHandle;

			[ReadOnly]
			public ComponentLookup<BuildingPropertyData> __Game_Prefabs_BuildingPropertyData_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<ResourceData> __Game_Prefabs_ResourceData_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<WorkplaceData> __Game_Prefabs_WorkplaceData_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<CommercialCompany> __Game_Companies_CommercialCompany_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<Population> __Game_City_Population_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<Tourism> __Game_City_Tourism_RO_ComponentLookup;

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public void __AssignHandles(ref SystemState state)
			{
				//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_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_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_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_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_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_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_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_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_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)
				__Unity_Entities_Entity_TypeHandle = ((SystemState)(ref state)).GetEntityTypeHandle();
				__Game_Prefabs_PrefabRef_RO_ComponentTypeHandle = ((SystemState)(ref state)).GetComponentTypeHandle<PrefabRef>(true);
				__Game_Prefabs_IndustrialProcessData_RO_ComponentTypeHandle = ((SystemState)(ref state)).GetComponentTypeHandle<IndustrialProcessData>(true);
				__Game_Buildings_Renter_RO_BufferTypeHandle = ((SystemState)(ref state)).GetBufferTypeHandle<Renter>(true);
				__Game_Prefabs_BuildingPropertyData_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<BuildingPropertyData>(true);
				__Game_Prefabs_ResourceData_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<ResourceData>(true);
				__Game_Prefabs_WorkplaceData_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<WorkplaceData>(true);
				__Game_Companies_CommercialCompany_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<CommercialCompany>(true);
				__Game_City_Population_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<Population>(true);
				__Game_City_Tourism_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<Tourism>(true);
			}
		}

		private static JobHandle baseDependency;

		private static TypeHandle __TypeHandle;

		public static NativeArray<CommercialUISystem.DemandData> m_DemandData;

		[HarmonyPatch(typeof(CommercialDemandSystem), "OnCreate")]
		[HarmonyPostfix]
		private static void CommercialDemandSystem_OnCreate()
		{
			//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)
			m_DemandData = new NativeArray<CommercialUISystem.DemandData>(EconomyUtils.ResourceCount, (Allocator)4, (NativeArrayOptions)1);
		}

		[HarmonyPatch(typeof(CommercialDemandSystem), "OnDestroy")]
		[HarmonyPrefix]
		private static bool CommercialDemandSystem_OnDestroy()
		{
			m_DemandData.Dispose();
			return true;
		}

		[HarmonyPatch(typeof(CommercialDemandSystem), "OnUpdate")]
		[HarmonyPrefix]
		private static bool CommercialDemandSystem_OnUpdate(CommercialDemandSystem __instance, ResourceSystem ___m_ResourceSystem, TaxSystem ___m_TaxSystem, CountEmploymentSystem ___m_CountEmploymentSystem, CountFreeWorkplacesSystem ___m_CountFreeWorkplacesSystem, CitySystem ___m_CitySystem, CountConsumptionSystem ___m_CountConsumptionSystem, CountCompanyDataSystem ___m_CountCompanyDataSystem, EntityQuery ___m_EconomyParameterQuery, EntityQuery ___m_DemandParameterQuery, EntityQuery ___m_FreeCommercialQuery, EntityQuery ___m_CommercialProcessDataQuery, NativeValue<int> ___m_CompanyDemand, NativeValue<int> ___m_BuildingDemand, NativeArray<int> ___m_DemandFactors, NativeArray<int> ___m_ResourceDemands, NativeArray<int> ___m_BuildingDemands, NativeArray<int> ___m_Consumption, NativeArray<int> ___m_FreeProperties, ref JobHandle ___m_WriteDependencies, JobHandle ___m_ReadDependencies, ref int ___m_LastCompanyDemand, ref int ___m_LastBuildingDemand)
		{
			//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_012d: 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_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_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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0174: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_01eb: 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_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: 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_0215: 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_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_0231: 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_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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_0252: Unknown result type (might be due to invalid IL or missing references)
			//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_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: 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_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: 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_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: 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_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: 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_02b3: 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_02bb: 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_02c7: 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_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: 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)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: 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_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: 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_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: 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_0343: 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_0345: 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_0349: 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_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: 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_0373: 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_038a: 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)
			if (!Plugin.FeatureCommercialDemand.Value)
			{
				return true;
			}
			if (!((EntityQuery)(ref ___m_DemandParameterQuery)).IsEmptyIgnoreFilter && !((EntityQuery)(ref ___m_EconomyParameterQuery)).IsEmptyIgnoreFilter)
			{
				___m_LastCompanyDemand = ___m_CompanyDemand.value;
				___m_LastBuildingDemand = ___m_BuildingDemand.value;
				JobHandle val = default(JobHandle);
				CommercialCompanyDatas commercialCompanyDatas = ___m_CountCompanyDataSystem.GetCommercialCompanyDatas(ref val);
				__TypeHandle.__Game_City_Tourism_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_City_Population_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Companies_CommercialCompany_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Prefabs_WorkplaceData_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Prefabs_ResourceData_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Prefabs_BuildingPropertyData_RO_ComponentLookup.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Buildings_Renter_RO_BufferTypeHandle.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Prefabs_IndustrialProcessData_RO_ComponentTypeHandle.Update(ref ((SystemBase)__instance).CheckedStateRef);
				__TypeHandle.__Game_Prefabs_PrefabRef_RO_ComponentTypeHandle.Update(ref ((SystemBase)__instance).CheckedStateRef);
				((EntityTypeHandle)(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle)).Update(ref ((SystemBase)__instance).CheckedStateRef);
				UpdateCommercialDemandJob updateCommercialDemandJob = default(UpdateCommercialDemandJob);
				JobHandle val2 = default(JobHandle);
				updateCommercialDemandJob.m_FreePropertyChunks = ((EntityQuery)(ref ___m_FreeCommercialQuery)).ToArchetypeChunkListAsync(AllocatorHandle.op_Implicit(((RewindableAllocator)(ref ((ComponentSystemBase)__instance).World.UpdateAllocator)).ToAllocator), ref val2);
				JobHandle val3 = default(JobHandle);
				updateCommercialDemandJob.m_CommercialProcessDataChunks = ((EntityQuery)(ref ___m_CommercialProcessDataQuery)).ToArchetypeChunkListAsync(AllocatorHandle.op_Implicit(((RewindableAllocator)(ref ((ComponentSystemBase)__instance).World.UpdateAllocator)).ToAllocator), ref val3);
				updateCommercialDemandJob.m_EntityType = __TypeHandle.__Unity_Entities_Entity_TypeHandle;
				updateCommercialDemandJob.m_PrefabType = __TypeHandle.__Game_Prefabs_PrefabRef_RO_ComponentTypeHandle;
				updateCommercialDemandJob.m_ProcessType = __TypeHandle.__Game_Prefabs_IndustrialProcessData_RO_ComponentTypeHandle;
				updateCommercialDemandJob.m_RenterType = __TypeHandle.__Game_Buildings_Renter_RO_BufferTypeHandle;
				updateCommercialDemandJob.m_BuildingPropertyDatas = __TypeHandle.__Game_Prefabs_BuildingPropertyData_RO_ComponentLookup;
				updateCommercialDemandJob.m_ResourceDatas = __TypeHandle.__Game_Prefabs_ResourceData_RO_ComponentLookup;
				updateCommercialDemandJob.m_WorkplaceDatas = __TypeHandle.__Game_Prefabs_WorkplaceData_RO_ComponentLookup;
				updateCommercialDemandJob.m_CommercialCompanies = __TypeHandle.__Game_Companies_CommercialCompany_RO_ComponentLookup;
				updateCommercialDemandJob.m_Populations = __TypeHandle.__Game_City_Population_RO_ComponentLookup;
				updateCommercialDemandJob.m_Tourisms = __TypeHandle.__Game_City_Tourism_RO_ComponentLookup;
				updateCommercialDemandJob.m_ResourcePrefabs = ___m_ResourceSystem.GetPrefabs();
				updateCommercialDemandJob.m_DemandParameters = ((EntityQuery)(ref ___m_DemandParameterQuery)).GetSingleton<DemandParameterData>();
				updateCommercialDemandJob.m_EconomyParameters = ((EntityQuery)(ref ___m_EconomyParameterQuery)).GetSingleton<EconomyParameterData>();
				JobHandle val4 = default(JobHandle);
				updateCommercialDemandJob.m_EmployableByEducation = ___m_CountEmploymentSystem.GetEmployableByEducation(ref val4);
				updateCommercialDemandJob.m_TaxRates = ___m_TaxSystem.GetTaxRates();
				JobHandle val5 = default(JobHandle);
				updateCommercialDemandJob.m_FreeWorkplaces = ___m_CountFreeWorkplacesSystem.GetFreeWorkplaces(ref val5);
				updateCommercialDemandJob.m_BaseConsumptionSum = ___m_ResourceSystem.BaseConsumptionSum;
				updateCommercialDemandJob.m_CompanyDemand = ___m_CompanyDemand;
				updateCommercialDemandJob.m_BuildingDemand = ___m_BuildingDemand;
				updateCommercialDemandJob.m_DemandFactors = ___m_DemandFactors;
				updateCommercialDemandJob.m_ResourceDemands = ___m_ResourceDemands;
				updateCommercialDemandJob.m_BuildingDemands = ___m_BuildingDemands;
				updateCommercialDemandJob.m_Productions = commercialCompanyDatas.m_SalesCapacities;
				updateCommercialDemandJob.m_Consumptions = ___m_Consumption;
				updateCommercialDemandJob.m_TotalAvailables = commercialCompanyDatas.m_CurrentAvailables;
				updateCommercialDemandJob.m_TotalMaximums = commercialCompanyDatas.m_TotalAvailables;
				updateCommercialDemandJob.m_Companies = commercialCompanyDatas.m_ServiceCompanies;
				updateCommercialDemandJob.m_FreeProperties = ___m_FreeProperties;
				updateCommercialDemandJob.m_Propertyless = commercialCompanyDatas.m_ServicePropertyless;
				updateCommercialDemandJob.m_TotalMaxWorkers = commercialCompanyDatas.m_MaxServiceWorkers;
				updateCommercialDemandJob.m_TotalCurrentWorkers = commercialCompanyDatas.m_CurrentServiceWorkers;
				updateCommercialDemandJob.m_City = ___m_CitySystem.City;
				JobHandle val6 = default(JobHandle);
				updateCommercialDemandJob.m_ActualConsumptions = ___m_CountConsumptionSystem.GetConsumptions(ref val6);
				updateCommercialDemandJob.m_DemandData = m_DemandData;
				baseDependency = IJobExtensions.Schedule<UpdateCommercialDemandJob>(updateCommercialDemandJob, JobUtils.CombineDependencies(baseDependency, ___m_ReadDependencies, val6, val2, val, val3, val4, val5));
				___m_WriteDependencies = baseDependency;
				___m_CountConsumptionSystem.AddConsumptionWriter(baseDependency);
				___m_ResourceSystem.AddPrefabsReader(baseDependency);
				___m_CountEmploymentSystem.AddReader(baseDependency);
				___m_CountFreeWorkplacesSystem.AddReader(baseDependency);
				___m_TaxSystem.AddReader(baseDependency);
			}
			return false;
		}

		[HarmonyPatch(typeof(CommercialDemandSystem), "OnCreateForCompiler")]
		[HarmonyPostfix]
		public static void CommercialDemandSystem_OnCreateForCompiler(CommercialDemandSystem __instance)
		{
			__TypeHandle.__AssignHandles(ref ((SystemBase)__instance).CheckedStateRef);
		}
	}
	[HarmonyPatch]
	internal class DeveloperPatches
	{
		[HarmonyPatch(typeof(DeveloperInfoUISystem), "UpdateZoneInfo")]
		[HarmonyPostfix]
		public static void DeveloperInfoUISystem_UpdateZoneInfo_Postfix(DeveloperInfoUISystem __instance, Entity entity, Entity prefab, GenericInfo info)
		{
			//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_0009: 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_0046: 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_004c: 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_0064: 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_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_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_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_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_003b: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager;
			if (!((EntityManager)(ref entityManager)).HasComponent<Building>(entity))
			{
				entityManager = ((ComponentSystemBase)__instance).EntityManager;
				entity = ((EntityManager)(ref entityManager)).GetComponentData<PropertyRenter>(entity).m_Property;
				entityManager = ((ComponentSystemBase)__instance).EntityManager;
				prefab = ((EntityManager)(ref entityManager)).GetComponentData<PrefabRef>(entity).m_Prefab;
			}
			entityManager = ((ComponentSystemBase)__instance).EntityManager;
			BuildingPropertyData componentData = ((EntityManager)(ref entityManager)).GetComponentData<BuildingPropertyData>(prefab);
			info.value += $" space {componentData.m_SpaceMultiplier} res {componentData.m_ResidentialProperties}";
		}

		[HarmonyPatch(typeof(DeveloperInfoUISystem), "UpdateStorageInfo")]
		[HarmonyPrefix]
		private static bool DeveloperInfoUISystem_UpdateStorageInfo_Prefix(DeveloperInfoUISystem __instance, Entity entity, Entity prefab, InfoList info)
		{
			//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_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_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_004d: 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_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_0086: 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)
			info.label = "Storage";
			StorageCompanyData val = default(StorageCompanyData);
			if (EntitiesExtensions.TryGetComponent<StorageCompanyData>(((ComponentSystemBase)__instance).EntityManager, prefab, ref val))
			{
				info.label = "Storage Company";
			}
			StorageLimitData val2 = default(StorageLimitData);
			DynamicBuffer<Resources> val3 = default(DynamicBuffer<Resources>);
			if (EntitiesExtensions.TryGetComponent<StorageLimitData>(((ComponentSystemBase)__instance).EntityManager, prefab, ref val2) && EntitiesExtensions.TryGetBuffer<Resources>(((ComponentSystemBase)__instance).EntityManager, entity, true, ref val3))
			{
				info.Add(new Item($"Storage Limit: {val2.m_Limit}"));
				for (int i = 0; i < val3.Length; i++)
				{
					info.Add(new Item($"{EconomyUtils.GetName(val3[i].m_Resource)} ({val3[i].m_Amount})"));
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(EconomyDebugSystem), "PrintCompanyDebug")]
		[HarmonyPrefix]
		public static bool EconomyDebugSystem_PrintCompanyDebug_Prefix(ComponentLookup<ResourceData> resourceDatas)
		{
			//IL_0005: 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_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_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_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_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_0047: 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_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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_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_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_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_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)
			//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)
			//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_00cf: 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)
			//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_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_00f9: 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_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_0117: 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_0134: 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_013f: 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_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_0159: 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_015f: 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_0173: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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_0192: 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_01a4: 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_01ad: 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_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_01bd: 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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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_01f4: 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)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: 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_01ff: 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_020b: 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_020f: 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_0215: 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_0219: 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_021b: 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_0232: 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_0238: 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_023f: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: 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_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: 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_0299: 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_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: 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_03c8: 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_03d1: 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_03e1: 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_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: 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_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: 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_042a: 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_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_0583: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: 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_04a1: 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_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: 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_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
			EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[3]
			{
				ComponentType.ReadOnly<IndustrialProcessData>(),
				ComponentType.ReadOnly<ServiceCompanyData>(),
				ComponentType.ReadOnly<WorkplaceData>()
			});
			EntityQuery val2 = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[4]
			{
				ComponentType.ReadOnly<IndustrialProcessData>(),
				ComponentType.ReadOnly<IndustrialCompanyData>(),
				ComponentType.ReadOnly<WorkplaceData>(),
				ComponentType.Exclude<StorageCompanyData>()
			});
			ResourcePrefabs prefabs = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<ResourceSystem>().GetPrefabs();
			NativeArray<ServiceCompanyData> val3 = ((EntityQuery)(ref val)).ToComponentDataArray<ServiceCompanyData>(AllocatorHandle.op_Implicit((Allocator)3));
			NativeArray<IndustrialProcessData> val4 = ((EntityQuery)(ref val)).ToComponentDataArray<IndustrialProcessData>(AllocatorHandle.op_Implicit((Allocator)3));
			NativeArray<WorkplaceData> val5 = ((EntityQuery)(ref val)).ToComponentDataArray<WorkplaceData>(AllocatorHandle.op_Implicit((Allocator)3));
			NativeArray<IndustrialProcessData> val6 = ((EntityQuery)(ref val2)).ToComponentDataArray<IndustrialProcessData>(AllocatorHandle.op_Implicit((Allocator)3));
			NativeArray<WorkplaceData> val7 = ((EntityQuery)(ref val2)).ToComponentDataArray<WorkplaceData>(AllocatorHandle.op_Implicit((Allocator)3));
			NativeArray<Entity> val8 = ((EntityQuery)(ref val2)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3));
			EntityQuery val9 = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<EconomyParameterData>() });
			NativeArray<EconomyParameterData> val10 = ((EntityQuery)(ref val9)).ToComponentDataArray<EconomyParameterData>(AllocatorHandle.op_Implicit((Allocator)3));
			EconomyParameterData val11 = val10[0];
			Debug.Log((object)"Company data per cell");
			for (int i = 0; i < val3.Length; i++)
			{
				ServiceCompanyData val12 = val3[i];
				IndustrialProcessData val13 = val4[i];
				BuildingData val14 = default(BuildingData);
				val14.m_LotSize = new int2(100, 10);
				BuildingData val15 = val14;
				ServiceAvailable val16 = default(ServiceAvailable);
				val16.m_MeanPriority = 0.5f;
				ServiceAvailable val17 = val16;
				WorkplaceData val18 = val5[i];
				SpawnableBuildingData val19 = default(SpawnableBuildingData);
				val19.m_Level = 1;
				SpawnableBuildingData val20 = val19;
				val19 = default(SpawnableBuildingData);
				val19.m_Level = 5;
				SpawnableBuildingData val21 = val19;
				float3 val22 = EconomyUtils.BuildPseudoTradeCost(5000f, val13, resourceDatas, prefabs);
				string text = "C " + EconomyUtils.GetName(val13.m_Output.m_Resource) + ": ";
				int num = Mathf.RoundToInt(val12.m_MaxWorkersPerCell * 1000f);
				int num2 = ServiceCompanySystem.EstimateDailyProfit(num, val17, val12, val15, val13, ref val11, val18, val20, prefabs, resourceDatas, val22);
				int num3 = ServiceCompanySystem.EstimateDailyProfit(num, val17, val12, val15, val13, ref val11, val18, val21, prefabs, resourceDatas, val22);
				int num4 = ServiceCompanySystem.EstimateDailyProduction(1f, num, (int)val20.m_Level, val12, val18, ref val11, val13.m_Output.m_Resource, 1000);
				int num5 = ServiceCompanySystem.EstimateDailyProduction(1f, num, (int)val21.m_Level, val12, val18, ref val11, val13.m_Output.m_Resource, 1000);
				int num6 = WorkProviderSystem.CalculateTotalWage(num, val18.m_Complexity, 1, val11);
				int num7 = WorkProviderSystem.CalculateTotalWage(num, val18.m_Complexity, 5, val11);
				text = text + "Production " + (float)num4 / 1000f + "|" + (float)num5 / 1000f + ", wage " + num6 + "|" + num7 + ", profit " + (float)num2 / 1000f + "|" + (float)num3 / 1000f + "), wpu = " + val12.m_WorkPerUnit;
				Debug.Log((object)text);
			}
			for (int j = 0; j < val6.Length; j++)
			{
				IndustrialProcessData val23 = val6[j];
				BuildingData val24 = default(BuildingData);
				val24.m_LotSize = new int2(100, 10);
				BuildingData val25 = val24;
				float3 val26 = EconomyUtils.BuildPseudoTradeCost(5000f, val23, resourceDatas, prefabs);
				WorkplaceData val27 = val7[j];
				SpawnableBuildingData val28 = default(SpawnableBuildingData);
				val28.m_Level = 1;
				SpawnableBuildingData val29 = val28;
				val28 = default(SpawnableBuildingData);
				val28.m_Level = 5;
				SpawnableBuildingData val30 = val28;
				string text2 = "I " + EconomyUtils.GetName(val23.m_Input1.m_Resource) + " => " + EconomyUtils.GetName(val23.m_Output.m_Resource) + ": ";
				int num8 = 0;
				float num9 = 0f;
				EntityManager entityManager2 = World.DefaultGameObjectInjectionWorld.EntityManager;
				int num10;
				float num11;
				int num12;
				int num13;
				if (((EntityManager)(ref entityManager2)).HasComponent<ExtractorCompanyData>(val8[j]))
				{
					int fittingWorkers = ExtractorAISystem.GetFittingWorkers(10000f, 1f, val23);
					num10 = ExtractorCompanySystem.EstimateDailyProduction(1f, fittingWorkers, 1, val27, val23, ref val11);
					num11 = ExtractorCompanySystem.EstimateDailyProfit(num10, fittingWorkers, val23, ref val11, val27, val29, prefabs, resourceDatas);
					num10 = Mathf.RoundToInt((float)num10 * 6.4f);
					num11 *= 6.4f;
					num12 = WorkProviderSystem.CalculateTotalWage(fittingWorkers, val27.m_Complexity, 1, val11);
					num13 = WorkProviderSystem.CalculateTotalWage(fittingWorkers, val27.m_Complexity, 5, val11);
				}
				else
				{
					int num14 = Mathf.RoundToInt(val23.m_MaxWorkersPerCell * 1000f);
					num11 = ProcessingCompanySystem.EstimateDailyProfit(num14, val23, val25, ref val11, val26, val27, val29, prefabs, resourceDatas);
					num9 = ProcessingCompanySystem.EstimateDailyProfit(num14, val23, val25, ref val11, val26, val27, val30, prefabs, resourceDatas);
					num10 = ProcessingCompanySystem.EstimateDailyProduction(1f, num14, (int)val29.m_Level, val27, val23, ref val11);
					num8 = ProcessingCompanySystem.EstimateDailyProduction(1f, num14, (int)val30.m_Level, val27, val23, ref val11);
					num12 = WorkProviderSystem.CalculateTotalWage(num14, val27.m_Complexity, 1, val11);
					num13 = WorkProviderSystem.CalculateTotalWage(num14, val27.m_Complexity, 5, val11);
				}
				text2 = text2 + "Production " + (float)num10 / 1000f + " | " + (float)num8 / 1000f + ", wage " + num12 + "|" + num13 + ", profit " + num11 / 1000f + "|" + num9 / 1000f + "), wpu = " + val23.m_WorkPerUnit;
				Debug.Log((object)text2);
			}
			val3.Dispose();
			val4.Dispose();
			val5.Dispose();
			val8.Dispose();
			val6.Dispose();
			val7.Dispose();
			val10.Dispose();
			return false;
		}
	}
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPatch(typeof(SystemOrder), "Initialize")]
		[HarmonyPostfix]
		public static void Initialize_Postfix(UpdateSystem updateSystem)
		{
			if (Plugin.FeatureNewCompanies.Value)
			{
				updateSystem.UpdateAt<ResourceBuyerSystem>((SystemUpdatePhase)12);
			}
			if (Plugin.FeatureConsumptionFix.Value)
			{
				updateSystem.UpdateAt<HouseholdBehaviorSystem>((SystemUpdatePhase)12);
			}
			if (Plugin.FeatureCommercialDemand.Value)
			{
				updateSystem.UpdateAt<CommercialUISystem>((SystemUpdatePhase)22);
			}
		}

		[HarmonyPatch(typeof(HouseholdBehaviorSystem), "OnUpdate")]
		[HarmonyPrefix]
		private static bool HouseholdBehaviorSystem_OnUpdate()
		{
			if (!Plugin.FeatureConsumptionFix.Value)
			{
				return true;
			}
			return false;
		}

		[HarmonyPatch(typeof(ResourceBuyerSystem), "OnUpdate")]
		[HarmonyPrefix]
		private static bool ResourceBuyerSystem_OnUpdate()
		{
			if (!Plugin.FeatureNewCompanies.Value)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch]
	[BepInPlugin("RealEco", "RealEco", "0.6.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private static ILog s_Log;

		public static ConfigEntry<bool> Logging;

		public static ConfigEntry<bool> ConfigDump;

		public static ConfigEntry<bool> FeaturePrefabs;

		public static ConfigEntry<bool> FeatureConsumptionFix;

		public static ConfigEntry<bool> FeatureNewCompanies;

		public static ConfigEntry<bool> FeatureCommercialDemand;

		internal static Mod Mod;

		public static void LogIf(string text, bool bMethod = false)
		{
			if (Logging.Value)
			{
				Log(text, bMethod);
			}
		}

		public static void Log(string text, bool bMethod = false)
		{
			if (bMethod)
			{
				text = GetCallingMethod(2) + ": " + text;
			}
			Logger.LogInfo((object)text);
			s_Log.Info((object)text);
		}

		public static void LogStack(string text)
		{
			Logger.LogInfo((object)(text + " STACKTRACE"));
			s_Log.logStackTrace = true;
			s_Log.Info((object)(text + "STACKTRACE"));
			s_Log.logStackTrace = false;
		}

		public static string GetCallingMethod(int frame)
		{
			MethodBase method = new StackTrace().GetFrame(frame).GetMethod();
			return method.DeclaringType?.ToString() + "." + method.Name;
		}

		private void Awake()
		{
			Mod = new Mod();
			Logger = ((BaseUnityPlugin)this).Logger;
			s_Log = Mod.log;
			Logging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Logging", false, "Enables detailed logging.");
			ConfigDump = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ConfigDump", false, "Saves configuration to a secondary xml file.");
			FeaturePrefabs = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "FeaturePrefabs", true, "Enables new prefab params.");
			FeatureConsumptionFix = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "FeatureConsumptionFix", true, "Enables Consumption Fix.");
			FeatureNewCompanies = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "FeatureNewCompanies", false, "Enables commercial companies for immaterial resources.");
			FeatureCommercialDemand = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "FeatureCommercialDemand", false, "Enables modded commercial demand and dedicated UI.");
			Log("Plugin RealEco is loaded!");
			MethodBase[] array = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "RealEco_Cities2Harmony").GetPatchedMethods().ToArray();
			Log("Plugin RealEco made patches! Patched methods: " + array.Length);
			MethodBase[] array2 = array;
			foreach (MethodBase methodBase in array2)
			{
				Log("Patched method: " + methodBase.Module.Name + ":" + methodBase.Name);
			}
			ConfigToolXml.LoadConfig();
		}

		[HarmonyPatch(typeof(ModManager), "InitializeMods")]
		[HarmonyPostfix]
		public static void InitializeMods(UpdateSystem updateSystem)
		{
			if (Mod != null)
			{
				Mod.OnLoad(updateSystem);
			}
			else
			{
				Log("Mod not created");
			}
		}
	}
	public class RealEco_Commercial : UIExtension
	{
		public readonly string extensionID = "realeco.commercial";

		public readonly string extensionContent;

		public readonly ExtensionType extensionType;

		public RealEco_Commercial()
		{
			extensionContent = ((UIExtension)this).LoadEmbeddedResource("RealEco.dist.commercial.js");
		}
	}
	[HarmonyPatch(typeof(PrefabSystem), "AddPrefab")]
	public static class PrefabSystem_AddPrefab_Patches
	{
		public static readonly Dictionary<ResourceInEditor, float> ResourcePriceDict = new Dictionary<ResourceInEditor, float>
		{
			{
				(ResourceInEditor)3,
				35f
			},
			{
				(ResourceInEditor)4,
				50f
			},
			{
				(ResourceInEditor)9,
				70f
			},
			{
				(ResourceInEditor)10,
				90f
			},
			{
				(ResourceInEditor)17,
				30f
			},
			{
				(ResourceInEditor)19,
				70f
			},
			{
				(ResourceInEditor)21,
				90f
			},
			{
				(ResourceInEditor)30,
				150f
			},
			{
				(ResourceInEditor)33,
				45f
			},
			{
				(ResourceInEditor)34,
				60f
			},
			{
				(ResourceInEditor)35,
				60f
			},
			{
				(ResourceInEditor)36,
				80f
			}
		};

		public static readonly Dictionary<ResourceInEditor, float> ResourceBaseConsumptionDict = new Dictionary<ResourceInEditor, float>
		{
			{
				(ResourceInEditor)3,
				15f
			},
			{
				(ResourceInEditor)4,
				25f
			},
			{
				(ResourceInEditor)21,
				20f
			},
			{
				(ResourceInEditor)31,
				20f
			},
			{
				(ResourceInEditor)32,
				15f
			},
			{
				(ResourceInEditor)33,
				15f
			},
			{
				(ResourceInEditor)34,
				30f
			},
			{
				(ResourceInEditor)35,
				25f
			},
			{
				(ResourceInEditor)36,
				20f
			},
			{
				(ResourceInEditor)37,
				15f
			}
		};

		public static readonly Dictionary<ResourceInEditor, int> ResourceCarConsumptionDict = new Dictionary<ResourceInEditor, int>
		{
			{
				(ResourceInEditor)11,
				5
			},
			{
				(ResourceInEditor)19,
				5
			},
			{
				(ResourceInEditor)21,
				5
			},
			{
				(ResourceInEditor)31,
				10
			},
			{
				(ResourceInEditor)36,
				10
			}
		};

		public static readonly Dictionary<string, float> MaxWorkersPerCellDict = new Dictionary<string, float>
		{
			{ "Industrial_ForestryExtractor", 0.04f },
			{ "Industrial_GrainExtractor", 0.05f },
			{ "Industrial_OreExtractor", 0.08f },
			{ "Industrial_OilExtractor", 0.11f },
			{ "Industrial_CoalMine", 0.14f },
			{ "Industrial_StoneQuarry", 0.12f },
			{ "Industrial_VegetableExtractor", 0.06f },
			{ "Industrial_LivestockExtractor", 0.09f },
			{ "Industrial_CottonExtractor", 0.07f },
			{ "Industrial_ConcreteFactory", 0.4f },
			{ "Industrial_PaperMill", 0.4f },
			{ "Industrial_VehicleFactory", 0.4f },
			{ "Industrial_SawMill", 0.4f },
			{ "Industrial_BioRefinery", 0.6f },
			{ "Industrial_ElectronicsFactory", 0.6f },
			{ "Industrial_ChemicalFactory", 0.6f },
			{ "Industrial_TextileFromCottonFactory", 0.6f }
		};

		public static readonly Dictionary<string, int> OutputAmountDict = new Dictionary<string, int>
		{
			{ "Industrial_FoodFactory", 3 },
			{ "Industrial_MachineryFactory", 1 },
			{ "Industrial_VehicleFactory", 1 },
			{ "Industrial_BeverageFromGrainFactory", 2 },
			{ "Industrial_BeverageFromVegetablesFactory", 2 },
			{ "Industrial_TextileFromCottonFactory", 2 },
			{ "Industrial_TextileFromLivestockFactory", 2 },
			{ "Industrial_TextileFromPetrochemicalsFactory", 2 },
			{ "Industrial_ConvenienceFoodFromLivestockFactory", 2 },
			{ "Industrial_ConvenienceFoodFromGrainFactory", 2 },
			{ "Office_SoftwareCompany", 10 },
			{ "Office_Bank", 6 },
			{ "Office_MediaCompany", 8 },
			{ "Office_TelecomCompany", 10 }
		};

		public static readonly Dictionary<string, WorkplaceComplexity> ComplexityDict = new Dictionary<string, WorkplaceComplexity>
		{
			{
				"Industrial_GrainExtractor",
				(WorkplaceComplexity)1
			},
			{
				"Industrial_OreExtractor",
				(WorkplaceComplexity)1
			},
			{
				"Industrial_VegetableExtractor",
				(WorkplaceComplexity)1
			},
			{
				"Industrial_LivestockExtractor",
				(WorkplaceComplexity)1
			},
			{
				"Industrial_CottonExtractor",
				(WorkplaceComplexity)1
			},
			{
				"Industrial_SawMill",
				(WorkplaceComplexity)1
			},
			{
				"Commercial_FoodStore",
				(WorkplaceComplexity)0
			},
			{
				"Commercial_Restaurant",
				(WorkplaceComplexity)0
			},
			{
				"Commercial_Bar",
				(WorkplaceComplexity)0
			},
			{
				"Commercial_ConvenienceFoodStore",
				(WorkplaceComplexity)0
			},
			{
				"Commercial_FashionStore",
				(WorkplaceComplexity)0
			},
			{
				"Industrial_MetalSmelter",
				(WorkplaceComplexity)2
			},
			{
				"Industrial_MachineryFactory",
				(WorkplaceComplexity)2
			},
			{
				"Industrial_BeverageFromGrainFactory",
				(WorkplaceComplexity)2
			},
			{
				"Industrial_BeverageFromVegetablesFactory",
				(WorkplaceComplexity)2
			},
			{
				"Industrial_FurnitureFactory",
				(WorkplaceComplexity)2
			},
			{
				"Industrial_ElectronicsFactory",
				(WorkplaceComplexity)3
			},
			{
				"Industrial_PlasticsFactory",
				(WorkplaceComplexity)3
			},
			{
				"Industrial_ChemicalFactory",
				(WorkplaceComplexity)3
			},
			{
				"Office_Bank",
				(WorkplaceComplexity)3
			},
			{
				"Office_MediaCompany",
				(WorkplaceComplexity)3
			}
		};

		public static readonly Dictionary<string, float> ProfitabilityDict = new Dictionary<string, float>
		{
			{ "Commercial_FoodStore", 80f },
			{ "Commercial_BookStore", 80f },
			{ "Commercial_VehicleStore", 50f },
			{ "Commercial_Restaurant", 80f },
			{ "Commercial_ElectronicsStore", 110f },
			{ "Commercial_GasStation", 50f },
			{ "Commercial_Hotel", 100f },
			{ "Commercial_Bar", 70f },
			{ "Commercial_ChemicalStore", 70f },
			{ "Commercial_ConvenienceFoodStore", 60f },
			{ "Commercial_DrugStore", 120f },
			{ "Commercial_FashionStore", 95f },
			{ "Commercial_FurnitureStore", 60f },
			{ "Commercial_LiquorStore", 75f },
			{ "Commercial_PlasticsStore", 70f },
			{ "Commercial_RecreactionStore", 70f },
			{ "Industrial_OilExtractor", 60f },
			{ "Industrial_CoalMine", 40f },
			{ "Industrial_FoodFactory", 45f },
			{ "Industrial_PaperMill", 40f },
			{ "Industrial_BioRefinery", 65f },
			{ "Industrial_ElectronicsFactory", 45f },
			{ "Industrial_MetalSmelter", 40f },
			{ "Industrial_OilRefinery", 50f },
			{ "Industrial_PlasticsFactory", 45f },
			{ "Industrial_SteelPlant", 45f },
			{ "Industrial_MachineryFactory", 30f },
			{ "Industrial_MineralPlant", 45f },
			{ "Industrial_ConcreteFactory", 40f },
			{ "Industrial_ChemicalFactory", 60f },
			{ "Industrial_PharmaceuticalsFactory", 50f },
			{ "Industrial_VehicleFactory", 45f },
			{ "Industrial_BeverageFromGrainFactory", 35f },
			{ "Industrial_BeverageFromVegetablesFactory", 30f },
			{ "Industrial_ConvenienceFoodFromLivestockFactory", 35f },
			{ "Industrial_TextileFromCottonFactory", 40f },
			{ "Industrial_TextileFromLivestockFactory", 40f },
			{ "Industrial_TextileFromPetrochemicalsFactory", 30f },
			{ "Industrial_SawMill", 35f },
			{ "Industrial_FurnitureFactory", 50f },
			{ "Industrial_ConvenienceFoodFromGrainFactory", 30f },
			{ "Office_SoftwareCompany", 90f },
			{ "Office_Bank", 90f },
			{ "Office_MediaCompany", 90f },
			{ "Office_TelecomCompany", 90f },
			{ "Industrial_WarehouseConvenienceFood", 15f },
			{ "Industrial_WarehouseGrain", 15f },
			{ "Industrial_WarehousePaper", 15f },
			{ "Industrial_WarehouseVehicles", 15f },
			{ "Industrial_WarehouseWood", 15f },
			{ "Industrial_WarehouseElectronics", 15f },
			{ "Industrial_WarehouseMetals", 15f },
			{ "Industrial_WarehouseOil", 15f },
			{ "Industrial_WarehousePlastics", 15f },
			{ "Industrial_WarehouseOre", 15f },
			{ "Industrial_WarehousePetrochemicals", 15f },
			{ "Industrial_WarehouseStone", 15f },
			{ "Industrial_WarehouseCoal", 15f },
			{ "Industrial_WarehouseLivestock", 15f },
			{ "Industrial_WarehouseCotton", 15f },
			{ "Industrial_WarehouseSteel", 15f },
			{ "Industrial_WarehouseMinerals", 15f },
			{ "Industrial_WarehouseConcrete", 15f },
			{ "Industrial_WarehouseMachinery", 15f },
			{ "Industrial_WarehouseChemicals", 15f },
			{ "Industrial_WarehousePharmaceuticals", 15f },
			{ "Industrial_WarehouseBeverages", 15f },
			{ "Industrial_WarehouseTextiles", 15f },
			{ "Industrial_WarehouseFood", 15f },
			{ "Industrial_WarehouseVegetables", 15f },
			{ "Industrial_WarehouseTimber", 15f },
			{ "Industrial_WarehouseFurniture", 15f }
		};

		private static readonly Dictionary<string, float> ZoneUpkeepDict = new Dictionary<string, float>
		{
			{ "EU Residential High", 500f },
			{ "NA Residential High", 500f },
			{ "EU Residential Mixed", 330f },
			{ "NA Residential Mixed", 330f },
			{ "EU Residential Medium", 200f },
			{ "NA Residential Medium", 200f },
			{ "Residential LowRent", 250f },
			{ "Office High", 350f }
		};

		private static readonly Dictionary<string, float> ZoneSpaceMultiplierDict = new Dictionary<string, float>
		{
			{ "EU Commercial Low", 1.2f },
			{ "NA Commercial Low", 1.2f },
			{ "Industrial Manufacturing", 1.4f },
			{ "Office High", 7f },
			{ "Office Low", 1.2f }
		};

		[HarmonyPrefix]
		public static bool EconomyPrefab_Prefix(object __instance, PrefabBase prefab)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (Plugin.FeaturePrefabs.Value && ((object)prefab).GetType().Name == "ServiceFeeParameterPrefab")
			{
				ServiceFeeParameterPrefab val = (ServiceFeeParameterPrefab)prefab;
				val.m_GarbageFee.m_Default = 0.4f;
				Plugin.Log($"Modded {((Object)prefab).name}: GarbageFee {val.m_GarbageFee.m_Default}");
			}
			return true;
		}

		[HarmonyPrefix]
		public static bool Companies_Prefix(PrefabBase prefab)
		{
			//IL_0077: 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)
			if (Plugin.FeaturePrefabs.Value && ((object)prefab).GetType().Name == "CompanyPrefab" && ((Object)prefab).name == "Industrial_BioRefinery")
			{
				ProcessingCompany component = ((ComponentBase)prefab).GetComponent<ProcessingCompany>();
				component.process.m_Input1.m_Amount = 1;
				Plugin.Log($"Modded {((Object)prefab).name}.ProcessingCompany: out {component.process.m_Output.m_Resource} {component.process.m_Output.m_Amount} in1 {component.process.m_Input1.m_Resource} {component.process.m_Input1.m_Amount}");
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class PrefabStore_Patches
	{
		private static bool CompaniesCreated = false;

		private static CompanyPrefab[] CompanyPrefabs = (CompanyPrefab[])(object)new CompanyPrefab[4];

		private static Dictionary<ResourceInEditor, ResourcePrefab> ResourcePrefabs = new Dictionary<ResourceInEditor, ResourcePrefab>();

		private static Dictionary<StatisticType, bool> StatisticsTypesToPatch = new Dictionary<StatisticType, bool>
		{
			{
				(StatisticType)45,
				true
			},
			{
				(StatisticType)8,
				true
			},
			{
				(StatisticType)7,
				true
			},
			{
				(StatisticType)9,
				true
			},
			{
				(StatisticType)10,
				true
			}
		};

		private static Dictionary<string, int> BrandsToPatch = new Dictionary<string, int>
		{
			{ "Cebeliverse", 0 },
			{ "ChirpyTeck", 0 },
			{ "DennyAlsLaw", 0 },
			{ "DLCHut", 0 },
			{ "FaultStudios", 0 },
			{ "FixedTraffic", 0 },
			{ "LuiboDigital", 0 },
			{ "Speltware", 0 },
			{ "Szoftver", 0 },
			{ "TechOMat", 0 },
			{ "Kapine", 1 },
			{ "LehtoElectronics", 1 },
			{ "Pteropus", 1 },
			{ "BanhammerBank", 2 },
			{ "CRIMoore", 2 },
			{ "Pihi", 2 },
			{ "SnafuInsurance", 2 },
			{ "StadelmannAndBardolf", 2 },
			{ "THELawAndAccounting", 2 },
			{ "AshtrainRecords", 3 },
			{ "BendyLetters", 3 },
			{ "BootAndBug", 3 },
			{ "IndieLizard", 3 },
			{ "MouthwaterPress", 3 },
			{ "Placesstages", 3 },
			{ "PNGMedia", 3 },
			{ "SingTapeRecords", 3 }
		};

		private static CompanyPrefab CreateNewCompanyPrefab(string prefabName, ResourceInEditor resource, WorkplaceComplexity complexity, float maxWorkersPerCell, float profitability)
		{
			//IL_0016: 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_0074: 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_00a8: 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_00d4: 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)
			CompanyPrefab val = ScriptableObject.CreateInstance<CompanyPrefab>();
			((Object)val).name = prefabName;
			((ComponentBase)val).prefab = (PrefabBase)(object)val;
			val.zone = (AreaType)2;
			val.profitability = profitability;
			ServiceCompany obj = ((PrefabBase)val).AddComponent<ServiceCompany>();
			obj.m_MaxService = 5000;
			obj.m_MaxWorkersPerCell = maxWorkersPerCell;
			ProcessingCompany obj2 = ((PrefabBase)val).AddComponent<ProcessingCompany>();
			obj2.transports = 1;
			obj2.process.m_Output.m_Resource = resource;
			obj2.process.m_Output.m_Amount = 1;
			obj2.process.m_Input1.m_Resource = resource;
			obj2.process.m_Input1.m_Amount = 1;
			((PrefabBase)val).AddComponent<StorageLimit>().storageLimit = 8000;
			Workplace obj3 = ((PrefabBase)val).AddComponent<Workplace>();
			obj3.m_Workplaces = 2;
			obj3.m_Complexity = complexity;
			obj3.m_EveningShiftProbability = 0.2f;
			obj3.m_NightShiftProbability = 0f;
			Plugin.Log($"New company prefab: {prefabName} {resource} wrk {complexity} wpc {maxWorkersPerCell} prof {profitability}");
			return val;
		}

		[HarmonyPatch(typeof(AssetCollection), "AddPrefabsTo")]
		[HarmonyPrefix]
		public static bool AssetCollection_AddPrefabsTo_Prefix(AssetCollection __instance)
		{
			if (Plugin.FeatureNewCompanies.Value && !CompaniesCreated && ((Object)__instance).name == "CompaniesCollection")
			{
				CompanyPrefabs[0] = CreateNewCompanyPrefab("Commercial_SoftwareStore", (ResourceInEditor)22, (WorkplaceComplexity)2, 0.45f, 350f);
				CompanyPrefabs[1] = CreateNewCompanyPrefab("Commercial_TelecomStore", (ResourceInEditor)35, (WorkplaceComplexity)2, 0.45f, 450f);
				CompanyPrefabs[2] = CreateNewCompanyPrefab("Commercial_FinancialStore", (ResourceInEditor)36, (WorkplaceComplexity)2, 0.5f, 400f);
				CompanyPrefabs[3] = CreateNewCompanyPrefab("Commercial_MediaStore", (ResourceInEditor)37, (WorkplaceComplexity)2, 0.45f, 500f);
				for (int i = 0; i < CompanyPrefabs.Length; i++)
				{
					__instance.m_Prefabs.Add((PrefabBase)(object)CompanyPrefabs[i]);
				}
				CompaniesCreated = true;
			}
			return true;
		}

		[HarmonyPatch(typeof(PrefabSystem), "AddPrefab")]
		[HarmonyPrefix]
		public static bool ZonePrefab_Prefix(PrefabBase prefab)
		{
			//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_00c3: Unknown result type (might be due to invalid IL or missing references)
			ZoneProperties val = default(ZoneProperties);
			if (Plugin.FeatureNewCompanies.Value && ((object)prefab).GetType().Name == "ZonePrefab" && prefab.TryGet<ZoneProperties>(ref val) && val.m_AllowedSold.Length != 0 && Array.IndexOf(val.m_AllowedSold, (ResourceInEditor)22) < 0)
			{
				List<ResourceInEditor> list = new List<ResourceInEditor>(val.m_AllowedSold);
				list.Add((ResourceInEditor)22);
				list.Add((ResourceInEditor)35);
				list.Add((ResourceInEditor)36);
				list.Add((ResourceInEditor)37);
				val.m_AllowedSold = list.ToArray();
				Resource resources = EconomyUtils.GetResources(val.m_AllowedSold);
				Plugin.Log(((Object)prefab).name + "." + ((Object)val).name + ".m_AllowedSold: " + EconomyUtils.GetNames(resources));
			}
			return true;
		}

		[HarmonyPatch(typeof(PrefabSystem), "AddPrefab")]
		[HarmonyPrefix]
		public static bool ResourcePrefab_Prefix(PrefabBase prefab)
		{
			//IL_0071: 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)
			TaxableResource val = default(TaxableResource);
			if (Plugin.FeatureNewCompanies.Value && ((object)prefab).GetType().Name == "ResourcePrefab" && prefab.TryGet<TaxableResource>(ref val))
			{
				bool flag = false;
				if (val.m_TaxAreas.Length == 1 && (int)val.m_TaxAreas[0] == 4)
				{
					val.m_TaxAreas = (TaxAreaType[])(object)new TaxAreaType[2]
					{
						(TaxAreaType)4,
						(TaxAreaType)2
					};
					flag = true;
					ResourcePrefab val2 = (ResourcePrefab)(object)((prefab is ResourcePrefab) ? prefab : null);
					if (!ResourcePrefabs.ContainsKey(val2.m_Resource))
					{
						ResourcePrefabs.Add(val2.m_Resource, val2);
					}
				}
				if (((Object)prefab).name == "ResourcePetrochemicals")
				{
					val.m_TaxAreas = (TaxAreaType[])(object)new TaxAreaType[2]
					{
						(TaxAreaType)2,
						(TaxAreaType)3
					};
					flag = true;
				}
				if (flag)
				{
					string text = "";
					for (int i = 0; i < val.m_TaxAreas.Length; i++)
					{
						text = text + ((object)(TaxAreaType)(ref val.m_TaxAreas[i])).ToString() + "|";
					}
					if (val.m_TaxAreas.Length == 0)
					{
						text = "None";
					}
					Plugin.Log(((Object)prefab).name + "." + ((Object)val).name + ".m_TaxAreas: " + text);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PrefabSystem), "AddPrefab")]
		[HarmonyPrefix]
		public static bool ResourceStatistic_Prefix(PrefabBase prefab)
		{
			//IL_0046: 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_0081: 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)
			if (Plugin.FeatureNewCompanies.Value && ((object)prefab).GetType() == typeof(ResourceStatistic) && ResourcePrefabs.Count == 4)
			{
				ResourceStatistic val = (ResourceStatistic)(object)((prefab is ResourceStatistic) ? prefab : null);
				if (StatisticsTypesToPatch.ContainsKey(((StatisticsPrefab)val).m_StatisticsType) && StatisticsTypesToPatch[((StatisticsPrefab)val).m_StatisticsType])
				{
					Plugin.Log($"{((Object)prefab).name}.{((object)val).GetType().Name}.m_StatisticsType: {((StatisticsPrefab)val).m_StatisticsType}");
					List<ResourcePrefab> list = new List<ResourcePrefab>(val.m_Resources);
					list.Add(ResourcePrefabs[(ResourceInEditor)22]);
					list.Add(ResourcePrefabs[(ResourceInEditor)35]);
					list.Add(ResourcePrefabs[(ResourceInEditor)36]);
					list.Add(ResourcePrefabs[(ResourceInEditor)37]);
					val.m_Resources = list.ToArray();
					StatisticsTypesToPatch[((StatisticsPrefab)val).m_StatisticsType] = false;
					string text = "";
					for (int i = 0; i < val.m_Resources.Length; i++)
					{
						text = text + ((object)(ResourceInEditor)(ref val.m_Resources[i].m_Resource)).ToString() + "|";
					}
					if (val.m_Resources.Length == 0)
					{
						text = "None";
					}
					Plugin.Log(((Object)prefab).name + "." + ((object)val).GetType().Name + ".m_Resources: " + text);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PrefabSystem), "AddPrefab")]
		[HarmonyPrefix]
		public static bool BrandPrefab_Prefix(PrefabBase prefab)
		{
			if (Plugin.FeatureNewCompanies.Value && ((object)prefab).GetType() == typeof(BrandPrefab) && CompaniesCreated)
			{
				BrandPrefab val = (BrandPrefab)(object)((prefab is BrandPrefab) ? prefab : null);
				if (BrandsToPatch.ContainsKey(((Object)val).name) && BrandsToPatch[((Object)val).name] != -1)
				{
					List<CompanyPrefab> list = new List<CompanyPrefab>(val.m_Companies);
					list.Add(CompanyPrefabs[BrandsToPatch[((Object)val).name]]);
					val.m_Companies = list.ToArray();
					BrandsToPatch[((Object)val).name] = -1;
					string text = "";
					for (int i = 0; i < val.m_Companies.Length; i++)
					{
						text = text + ((Object)val.m_Companies[i]).name + "|";
					}
					if (val.m_Companies.Length == 0)
					{
						text = "None";
					}
					Plugin.Log(((Object)prefab).name + "." + ((object)val).GetType().Name + ": " + text);
				}
			}
			return true;
		}
	}
	public class LocaleEN : IDictionarySource
	{
		public IEnumerable<KeyValuePair<string, string>> ReadEntries(IList<IDictionaryEntryError> errors, Dictionary<string, int> indexCounts)
		{
			LocalizationManager manager = GameManager.instance.localizationManager;
			Mod.log.Info((object)("Registering labels for LocaleId = active " + manager.activeLocaleId + " / fallback " + manager.fallbackLocaleId));
			Dictionary<string, string> dict = new Dictionary<string, string>();
			AddResource((Resource)2097152);
			AddResource((Resource)17179869184L);
			AddResource((Resource)34359738368L);
			AddResource((Resource)68719476736L);
			return dict;
			void AddResource(Resource res)
			{
				//IL_0010: 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_0037: 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_0083: 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)
				string value = default(string);
				if (manager.activeDictionary.TryGetValue($"Resources.TITLE[{res}]", ref value))
				{
					dict.Add($"StatisticsPanel.STAT_TITLE[{$"ServiceCount{res}"}]", value);
					dict.Add($"StatisticsPanel.STAT_TITLE[{$"ServiceMaxWorkers{res}"}]", value);
					dict.Add($"StatisticsPanel.STAT_TITLE[{$"ServiceWealth{res}"}]", value);
					dict.Add($"StatisticsPanel.STAT_TITLE[{$"ServiceWorkers{res}"}]", value);
				}
				else
				{
					Mod.log.Info((object)$"Warning. Failed to get localized name for {res}.");
				}
			}
		}

		public void Unload()
		{
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "RealEco";

		public const string PLUGIN_NAME = "RealEco";

		public const string PLUGIN_VERSION = "0.6.1";
	}
}
namespace RealEco.Systems
{
	[CompilerGenerated]
	public class CommercialUISystem : UISystemBase
	{
		public struct DemandData
		{
			public Resource Resource;

			public int Demand;

			public int Building;

			public int Free;

			public int Companies;

			public int Workers;

			public int SvcFactor;

			public int SvcPercent;

			public int CapFactor;

			public int CapPercent;

			public int CapPerCompany;

			public int WrkFactor;

			public int WrkPercent;

			public int EduFactor;

			public int TaxFactor;

			public DemandData(Resource resource)
			{
				//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)
				Demand = 0;
				Building = 0;
				Free = 0;
				Companies = 0;
				Workers = 0;
				SvcFactor = 0;
				SvcPercent = 0;
				CapFactor = 0;
				CapPercent = 0;
				CapPerCompany = 0;
				WrkFactor = 0;
				WrkPercent = 0;
				EduFactor = 0;
				TaxFactor = 0;
				Resource = resource;
			}
		}

		private const string kGroup = "realEco";

		private SimulationSystem m_SimulationSystem;

		private RawValueBinding m_uiResults;

		private NativeArray<DemandData> m_Results;

		public override GameMode gameMode => (GameMode)2;

		private static void WriteData(IJsonWriter writer, DemandData data)
		{
			writer.TypeBegin("DemandData");
			writer.PropertyName("resource");
			writer.Write(((object)(Resource)(ref data.Resource)).ToString());
			writer.PropertyName("demand");
			writer.Write(data.Demand);
			writer.PropertyName("building");
			writer.Write(data.Building);
			writer.PropertyName("free");
			writer.Write(data.Free);
			writer.PropertyName("companies");
			writer.Write(data.Companies);
			writer.PropertyName("workers");
			writer.Write(data.Workers);
			writer.PropertyName("svcfactor");
			writer.Write(data.SvcFactor);
			writer.PropertyName("svcpercent");
			writer.Write(data.SvcPercent);
			writer.PropertyName("capfactor");
			writer.Write(data.CapFactor);
			writer.PropertyName("cappercent");
			writer.Write(data.CapPercent);
			writer.PropertyName("cappercompany");
			writer.Write(data.CapPerCompany);
			writer.PropertyName("wrkfactor");
			writer.Write(data.WrkFactor);
			writer.PropertyName("wrkpercent");
			writer.Write(data.WrkPercent);
			writer.PropertyName("edufactor");
			writer.Write(data.EduFactor);
			writer.PropertyName("taxfactor");
			writer.Write(data.TaxFactor);
			writer.TypeEnd();
		}

		[Preserve]
		protected override void OnCreate()
		{
			//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_0036: Expected O, but got Unknown
			//IL_003b: Expected O, but got Unknown
			((UISystemBase)this).OnCreate();
			m_SimulationSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<SimulationSystem>();
			RawValueBinding val = new RawValueBinding("realEco", "commercialDemand", (Action<IJsonWriter>)delegate(IJsonWriter binder)
			{
				JsonWriterExtensions.ArrayBegin(binder, m_Results.Length);
				for (int i = 0; i < m_Results.Length; i++)
				{
					WriteData(binder, m_Results[i]);
				}
				binder.ArrayEnd();
			});
			RawValueBinding val2 = val;
			m_uiResults = val;
			((UISystemBase)this).AddBinding((IBinding)(object)val2);
			Plugin.Log("CommercialUISystem created.");
		}

		[Preserve]
		protected override void OnUpdate()
		{
			//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)
			if (m_SimulationSystem.frameIndex % 64 == 17)
			{
				m_Results = CommercialDemandSystem_Patches.m_DemandData;
				m_uiResults.Update();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void __AssignQueries(ref SystemState state)
		{
		}

		protected override void OnCreateForCompiler()
		{
			((ComponentSystemBase)this).OnCreateForCompiler();
			__AssignQueries(ref ((SystemBase)this).CheckedStateRef);
		}

		[Preserve]
		public CommercialUISystem()
		{
		}
	}
	[CompilerGenerated]
	public class HouseholdBehaviorSystem : GameSystemBase
	{
		private struct ProcessConsumptionJob : IJob
		{
			public NativeQueue<ResourceStack> m_Queue;

			public NativeArray<int> m_ConsumptionAccumulator;

			public NativeQueue<int> m_DebugResourceQueue;

			public NativeArray<int> m_DebugResourceCounter;

			public NativeArray<int> m_DebugResourceCounter2;

			[ReadOnly]
			public ResourcePrefabs m_ResourcePrefabs;

			[ReadOnly]
			public ComponentLookup<ResourceData> m_ResourceDatas;

			public void Execute()
			{
				//IL_0002: 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_002c: 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_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_004f: 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_00b2: 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)
				int2 val = default(int2);
				ResourceStack val2 = default(ResourceStack);
				ref NativeArray<int> consumptionAccumulator;
				while (m_Queue.TryDequeue(ref val2))
				{
					consumptionAccumulator = ref m_ConsumptionAccumulator;
					int resourceIndex = EconomyUtils.GetResourceIndex(val2.m_Resource);
					consumptionAccumulator[resourceIndex] += val2.m_Amount;
					float price = m_ResourceDatas[((ResourcePrefabs)(ref m_ResourcePrefabs))[val2.m_Resource]].m_Price;
					val.x += Mathf.RoundToInt((float)val2.m_Amount * price);
				}
				int num = default(int);
				while (m_DebugResourceQueue.TryDequeue(ref num))
				{
					val.y += num;
				}
				consumptionAccumulator = ref m_DebugResourceCounter;
				consumptionAccumulator[0] = consumptionAccumulator[0] + val.x;
				consumptionAccumulator = ref m_DebugResourceCounter2;
				consumptionAccumulator[0] = consumptionAccumulator[0] + val.y;
			}
		}

		[BurstCompile]
		private struct HouseholdTickJob : IJobChunk
		{
			[ReadOnly]
			public EntityTypeHandle m_EntityType;

			public ComponentTypeHandle<Household> m_HouseholdType;

			public ComponentType