Decompiled source of Economy Rebalance v0.6.1
0Harmony.dll
Decompiled 8 months ago
The result has been truncated due to the large size, download it to view full contents!
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 8 months ago
The result has been truncated due to the large size, download it to view full contents!
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