using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyVersion("0.1.1.0")] public static class CompatPatcher { public static IEnumerable TargetDLLs => new string[1] { "assembly_valheim.dll" }; public static void Patch(AssemblyDefinition assembly) { //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_026c: 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_0296: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Expected O, but got Unknown //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04ef: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: 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_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0549: 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_0575: Unknown result type (might be due to invalid IL or missing references) //IL_057a: 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_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown ManualLogSource val = Logger.CreateLogSource("Olive Valheim 1.0 Compatibility"); ModuleDefinition mainModule = assembly.MainModule; if (mainModule.Mvid != new Guid("db11c804-ebef-403d-8e77-ac219f14bf46")) { throw new NotSupportedException("Unsupported Valheim assembly: " + mainModule.Mvid.ToString() + ". Remove this experimental patch after game updates; it requires a new compatibility check."); } if (((IEnumerable)mainModule.Types).Any((TypeDefinition t) => ((MemberReference)t).Name == "OliveCompatApplied")) { return; } TypeDefinition val2 = Type(mainModule, "ZRoutedRpc"); FieldDefinition val3 = ((IEnumerable)val2.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "Everybody"); if (!val3.IsLiteral || Convert.ToInt64(val3.Constant) != 0) { throw new InvalidOperationException("Unexpected Everybody constant."); } val3.Attributes = (FieldAttributes)54; val3.HasConstant = false; Bridge(mainModule, "Character", "Message", 5, 4); Bridge(mainModule, "EffectList", "Create", 6, 5); Bridge(mainModule, "Inventory", "AddItem", 8, 7); MethodDefinition[] array = ((IEnumerable)Type(mainModule, "SEMan").Methods).Where((MethodDefinition m) => ((MemberReference)m).Name == "AddStatusEffect" && ((MethodReference)m).Parameters.Count == 5).ToArray(); foreach (MethodDefinition target in array) { Bridge(mainModule, target, 4); } MethodDefinition[] array2 = ((IEnumerable)Type(mainModule, "Terminal/ConsoleCommand").Methods).Where((MethodDefinition m) => m.IsConstructor && ((MethodReference)m).Parameters.Count == 13).ToArray(); foreach (MethodDefinition target2 in array2) { Bridge(mainModule, target2, 12, 8); } MethodDefinition val4 = ((IEnumerable)Type(mainModule, "Player").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ActivateGuardianPower"); int num3 = 0; Enumerator enumerator = val4.Body.Instructions.GetEnumerator(); try { while (enumerator.MoveNext()) { Instruction current = enumerator.Current; if (current.Operand is MethodReference && ((MemberReference)(MethodReference)current.Operand).FullName == "StatusEffect SEMan::AddStatusEffect(System.Int32,System.Boolean,System.Int32,System.Single,System.Int16)") { if (current.Previous.OpCode != OpCodes.Ldc_I4_M1) { throw new InvalidOperationException("Unexpected guardian power IL"); } current.Previous.OpCode = OpCodes.Nop; current.Operand = ((IEnumerable)Type(mainModule, "SEMan").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "AddStatusEffect" && ((MethodReference)m).Parameters.Count == 4 && ((MemberReference)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType).FullName == "System.Int32"); num3++; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (num3 != 1) { throw new InvalidOperationException("Guardian call count"); } MethodDefinition val5 = ((IEnumerable)Type(mainModule, "InventoryGui").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "DoCrafting"); Enumerator enumerator2 = val5.Body.Instructions.GetEnumerator(); try { while (enumerator2.MoveNext()) { Instruction current2 = enumerator2.Current; if (current2.Operand is MethodReference && ((MemberReference)(MethodReference)current2.Operand).FullName == "ItemDrop/ItemData Inventory::AddItem(System.String,System.Int32,System.Int32,System.Int32,System.Int64,System.String,System.Boolean,System.Boolean)") { if (current2.Previous.OpCode != OpCodes.Ldc_I4_0) { throw new InvalidOperationException("Unexpected crafting IL"); } current2.Previous.OpCode = OpCodes.Nop; current2.Operand = ((IEnumerable)Type(mainModule, "Inventory").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "AddItem" && ((MethodReference)m).Parameters.Count == 7); } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } MethodDefinition val6 = ((IEnumerable)Type(mainModule, "ItemDrop/ItemData").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "GetTooltip" && ((MethodReference)m).Parameters.Count == 6); MethodDefinition val7 = CloneBodyMethod(val6, "OliveCompat_GetTooltipImpl"); MethodDefinition val8 = Bridge(mainModule, val7, 5); ((MemberReference)val8).Name = "GetTooltip"; val8.Attributes = (MethodAttributes)150; val6.Body = new MethodBody(val6); ILProcessor iLProcessor = val6.Body.GetILProcessor(); Instruction val9 = Instruction.Create(OpCodes.Nop); iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val6).Parameters[5]); iLProcessor.Emit(OpCodes.Brtrue, val9); for (int num4 = 0; num4 < 5; num4++) { iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val6).Parameters[num4]); } iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val8); iLProcessor.Emit(OpCodes.Ret); iLProcessor.Append(val9); Enumerator enumerator3 = ((MethodReference)val6).Parameters.GetEnumerator(); try { while (enumerator3.MoveNext()) { ParameterDefinition current3 = enumerator3.Current; iLProcessor.Emit(OpCodes.Ldarg, current3); } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val7); iLProcessor.Emit(OpCodes.Ret); mainModule.Types.Add(new TypeDefinition("", "OliveCompatApplied", (TypeAttributes)0, mainModule.TypeSystem.Object)); ModLoader.GamePatched = true; val.LogInfo((object)"Applied compatibility bridges for Valheim 1.0.7. Modpack adaptations active; gameplay and multiplayer testing required."); } public static void Finish() { if (ModLoader.GamePatched) { ModLoader.Install(); } } private static TypeDefinition Type(ModuleDefinition m, string name) { return m.GetTypes().Single((TypeDefinition t) => ((MemberReference)t).FullName == name); } private static void Bridge(ModuleDefinition m, string type, string name, int currentCount, int oldCount) { Bridge(m, ((IEnumerable)Type(m, type).Methods).Single((MethodDefinition x) => ((MemberReference)x).Name == name && ((MethodReference)x).Parameters.Count == currentCount), oldCount); } private static MethodDefinition Bridge(ModuleDefinition mod, MethodDefinition target, int oldCount, int missingIndex = -1) { //IL_0008: 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_0018: 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_0025: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0178: 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_0132: Unknown result type (might be due to invalid IL or missing references) MethodDefinition val = new MethodDefinition(((MemberReference)target).Name, (MethodAttributes)(target.Attributes & 0xFFBF & 0xFEFF), ((MethodReference)target).ReturnType); Dictionary dictionary = new Dictionary(); for (int i = 0; i < ((MethodReference)target).Parameters.Count; i++) { if (!((missingIndex >= 0) ? (i == missingIndex) : (i >= oldCount))) { ParameterDefinition val2 = ((MethodReference)target).Parameters[i]; ParameterDefinition val3 = new ParameterDefinition(((ParameterReference)val2).Name, val2.Attributes, ((ParameterReference)val2).ParameterType); if (val2.HasConstant) { val3.Constant = val2.Constant; } ((MethodReference)val).Parameters.Add(val3); dictionary.Add(i, val3); } } if (((MethodReference)val).Parameters.Count != oldCount) { throw new InvalidOperationException("Bridge parameter count."); } target.DeclaringType.Methods.Add(val); ILProcessor iLProcessor = val.Body.GetILProcessor(); if (((MethodReference)target).HasThis) { iLProcessor.Emit(OpCodes.Ldarg_0); } for (int j = 0; j < ((MethodReference)target).Parameters.Count; j++) { if (dictionary.TryGetValue(j, out var value)) { iLProcessor.Emit(OpCodes.Ldarg, value); } else { Default(iLProcessor, ((MethodReference)target).Parameters[j], val.Body); } } iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)target); iLProcessor.Emit(OpCodes.Ret); return val; } private static void Default(ILProcessor il, ParameterDefinition p, MethodBody body) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (p.HasConstant && p.Constant != null) { if (p.Constant is bool) { il.Emit(((bool)p.Constant) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); } else if (p.Constant is float) { il.Emit(OpCodes.Ldc_R4, (float)p.Constant); } else { il.Emit(OpCodes.Ldc_I4, Convert.ToInt32(p.Constant)); } } else if ((int)((ParameterReference)p).ParameterType.MetadataType == 2) { il.Emit(OpCodes.Ldc_I4_0); } else if (((ParameterReference)p).ParameterType.IsValueType) { VariableDefinition val = new VariableDefinition(((ParameterReference)p).ParameterType); body.Variables.Add(val); body.InitLocals = true; il.Emit(OpCodes.Ldloca, val); il.Emit(OpCodes.Initobj, ((ParameterReference)p).ParameterType); il.Emit(OpCodes.Ldloc, val); } else { il.Emit(OpCodes.Ldnull); } } private static MethodDefinition CloneBodyMethod(MethodDefinition source, string name) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_032a: 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_0342: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Expected O, but got Unknown MethodDefinition val = new MethodDefinition(name, (MethodAttributes)145, ((MethodReference)source).ReturnType); Enumerator enumerator = ((MethodReference)source).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; ParameterDefinition val2 = new ParameterDefinition(((ParameterReference)current).Name, current.Attributes, ((ParameterReference)current).ParameterType); if (current.HasConstant) { val2.Constant = current.Constant; } ((MethodReference)val).Parameters.Add(val2); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } source.DeclaringType.Methods.Add(val); val.Body.InitLocals = source.Body.InitLocals; val.Body.MaxStackSize = source.Body.MaxStackSize; Enumerator enumerator2 = source.Body.Variables.GetEnumerator(); try { while (enumerator2.MoveNext()) { VariableDefinition current2 = enumerator2.Current; val.Body.Variables.Add(new VariableDefinition(((VariableReference)current2).VariableType)); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } Dictionary map = new Dictionary(); Enumerator enumerator3 = source.Body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current3 = enumerator3.Current; Instruction val3 = Instruction.Create(OpCodes.Nop); val3.OpCode = current3.OpCode; val3.Operand = current3.Operand; val.Body.Instructions.Add(val3); map.Add(current3, val3); } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } Enumerator enumerator4 = val.Body.Instructions.GetEnumerator(); try { while (enumerator4.MoveNext()) { Instruction current4 = enumerator4.Current; if (current4.Operand is Instruction) { current4.Operand = map[(Instruction)current4.Operand]; } else if (current4.Operand is Instruction[]) { current4.Operand = ((Instruction[])current4.Operand).Select((Instruction x) => map[x]).ToArray(); } else if (current4.Operand is VariableDefinition) { current4.Operand = val.Body.Variables[((VariableReference)(VariableDefinition)current4.Operand).Index]; } else if (current4.Operand is ParameterDefinition) { current4.Operand = ((MethodReference)val).Parameters[((ParameterReference)(ParameterDefinition)current4.Operand).Index]; } } } finally { ((IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose(); } Enumerator enumerator5 = source.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator5.MoveNext()) { ExceptionHandler current5 = enumerator5.Current; val.Body.ExceptionHandlers.Add(new ExceptionHandler(current5.HandlerType) { CatchType = current5.CatchType, TryStart = map[current5.TryStart], TryEnd = ((current5.TryEnd == null) ? null : map[current5.TryEnd]), HandlerStart = map[current5.HandlerStart], HandlerEnd = ((current5.HandlerEnd == null) ? null : map[current5.HandlerEnd]), FilterStart = ((current5.FilterStart == null) ? null : map[current5.FilterStart]) }); } } finally { ((IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose(); } return val; } } public static class ModLoader { public static bool GamePatched; private static readonly Dictionary Loaded = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary Locations = new Dictionary(); private static readonly Dictionary Hashes = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "CreatureLevelControl.dll", "601739B998F956BC49A871A4B0C7761E1F6389E5F8604D3234868F9E92D2761E" }, { "PassivePowers.dll", "8C03D1C5ECDDDFFE357A884D1F48CC3D764E06210745FA875ABC1A0E2A76CAD3" }, { "TargetPortal.dll", "EFA04ED04C7C6381C502033ECCDB2D24BED0DDF72973D002F6E768B1531EF0FF" }, { "Seasonality.dll", "56B7713D9597F537772CE29CA4C560F786BBA28B8DE684D7452A1387352F0F24" } }; public static void Install() { //IL_0006: 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_0054: Expected O, but got Unknown new Harmony("olive.valheim10compat.loader").Patch((MethodBase)typeof(Assembly).GetMethod("LoadFile", new Type[1] { typeof(string) }), new HarmonyMethod(typeof(ModLoader).GetMethod("LoadFilePrefix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static string OriginalLocation(Assembly assembly) { string value; return Locations.TryGetValue(assembly, out value) ? value : assembly.Location; } public static bool LoadFilePrefix(string __0, ref Assembly __result) { string fullPath = Path.GetFullPath(__0); if (!fullPath.StartsWith(Path.GetFullPath(Paths.PluginPath) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) { return true; } if (!Hashes.TryGetValue(Path.GetFileName(fullPath), out var value)) { return true; } lock (Loaded) { if (Loaded.TryGetValue(fullPath, out __result)) { return false; } byte[] array = File.ReadAllBytes(fullPath); using (SHA256 sHA = SHA256.Create()) { if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "") != value) { throw new InvalidOperationException("Unsupported mod binary: " + fullPath + ". Update compatibility package before using this version."); } } string runtimePath = Directory.GetFiles(Paths.PluginPath, "OliveRuntimeBridge.dll", SearchOption.AllDirectories).Single(); array = Transform(array, runtimePath, Paths.ManagedPath, Paths.BepInExAssemblyDirectory); __result = Assembly.Load(array); Loaded.Add(fullPath, __result); Locations.Add(__result, fullPath); Logger.CreateLogSource("Olive Compat Loader").LogInfo((object)("Adapted in memory: " + Path.GetFileName(fullPath))); return false; } } public static byte[] Transform(byte[] bytes, string runtimePath, string managedPath, string corePath) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //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_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Expected O, but got Unknown //IL_02de: 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_0259: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_031b: 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_0447: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_072f: Unknown result type (might be due to invalid IL or missing references) //IL_0781: Unknown result type (might be due to invalid IL or missing references) DefaultAssemblyResolver val = new DefaultAssemblyResolver(); ((BaseAssemblyResolver)val).AddSearchDirectory(Path.GetDirectoryName(runtimePath)); ((BaseAssemblyResolver)val).AddSearchDirectory(managedPath); ((BaseAssemblyResolver)val).AddSearchDirectory(corePath); AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly((Stream)new MemoryStream(bytes), new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val }); try { AssemblyDefinition runtime = AssemblyDefinition.ReadAssembly(runtimePath); try { ModuleDefinition mod = val2.MainModule; Func func = (string name) => mod.ImportReference((MethodReference)(object)((IEnumerable)runtime.MainModule.GetType("OliveRuntimeBridge").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == name)); foreach (TypeDefinition type in mod.GetTypes()) { Enumerator enumerator2 = type.CustomAttributes.GetEnumerator(); try { while (enumerator2.MoveNext()) { CustomAttribute current2 = enumerator2.Current; FixAttribute(current2); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } Enumerator enumerator3 = type.Methods.GetEnumerator(); try { while (enumerator3.MoveNext()) { MethodDefinition current3 = enumerator3.Current; Enumerator enumerator4 = current3.CustomAttributes.GetEnumerator(); try { while (enumerator4.MoveNext()) { CustomAttribute current4 = enumerator4.Current; FixAttribute(current4); } } finally { ((IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose(); } if (!current3.HasBody) { continue; } if (((MemberReference)type).Name == "PatchCookingStationItemMultiplier" && ((MemberReference)current3).Name == "multiplyItemSpawn") { ((MethodReference)current3).Parameters.Add(new ParameterDefinition("cheated", (ParameterAttributes)0, mod.TypeSystem.Boolean)); } if (((AssemblyNameReference)val2.Name).Name == "Seasonality" && ((MemberReference)type).Name == "GetAvailableEnvironments_Patch" && ((MemberReference)current3).Name == "Postfix") { ((ParameterReference)((MethodReference)current3).Parameters[0]).ParameterType = ((ParameterReference)func("SectorBiome").Parameters[0]).ParameterType; ILProcessor iLProcessor = current3.Body.GetILProcessor(); Instruction[] array = current3.Body.Instructions.ToArray(); foreach (Instruction val3 in array) { if (val3.OpCode == OpCodes.Ldarg_0) { iLProcessor.InsertAfter(val3, Instruction.Create(OpCodes.Call, func("SectorBiome"))); } } } if (((AssemblyNameReference)val2.Name).Name == "TargetPortal" && ((MemberReference)current3).Name == "GetAllZDOsWithPrefabIterative") { current3.Body = new MethodBody(current3); ILProcessor iLProcessor2 = current3.Body.GetILProcessor(); Enumerator enumerator5 = ((MethodReference)current3).Parameters.GetEnumerator(); try { while (enumerator5.MoveNext()) { ParameterDefinition current5 = enumerator5.Current; iLProcessor2.Emit(OpCodes.Ldarg, current5); } } finally { ((IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose(); } iLProcessor2.Emit(OpCodes.Call, func("FindZdos")); iLProcessor2.Emit(OpCodes.Ret); continue; } Instruction[] array2 = current3.Body.Instructions.ToArray(); foreach (Instruction val4 in array2) { if (val4.OpCode == OpCodes.Ldstr && (string)val4.Operand == "OnMapRightClick") { val4.Operand = "RemovePinUnderPointer"; } object operand = val4.Operand; FieldReference val5 = (FieldReference)((operand is FieldReference) ? operand : null); if (val5 != null) { string text = null; if (((MemberReference)((MemberReference)val5).DeclaringType).FullName == "PlayerProfile" && ((MemberReference)val5).Name == "m_enemyStats") { text = "EnemyStats"; } if (((MemberReference)((MemberReference)val5).DeclaringType).FullName == "Minimap" && ((MemberReference)val5).Name == "noForest") { text = "NoForest"; } if (text != null) { val4.OpCode = OpCodes.Call; val4.Operand = func(text); } if (((MemberReference)((MemberReference)val5).DeclaringType).FullName == "PieceTable" && ((MemberReference)val5).Name == "m_availablePieces") { ((MemberReference)val5).Name = "m_availablePiecesByCategory"; } } object operand2 = val4.Operand; MethodReference val6 = (MethodReference)((operand2 is MethodReference) ? operand2 : null); if (val6 == null) { continue; } string text2 = null; if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "Inventory" && ((MemberReference)val6).Name == "Changed" && val6.Parameters.Count == 0) { text2 = "Changed"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "Inventory" && ((MemberReference)val6).Name == "AddItem" && val6.Parameters.Count == 7) { text2 = "AddItem"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "CookingStation" && ((MemberReference)val6).Name == "SpawnItem" && val6.Parameters.Count == 3) { if (((MemberReference)current3).Name != "multiplyItemSpawn") { throw new InvalidOperationException("Unexpected SpawnItem caller"); } current3.Body.GetILProcessor().InsertBefore(val4, Instruction.Create(OpCodes.Ldarg, ((IEnumerable)((MethodReference)current3).Parameters).Last())); text2 = "SpawnItem"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "ZDO" && ((MemberReference)val6).Name == "GetSector" && ((MemberReference)val6.ReturnType).FullName == "Vector2i") { text2 = "GetSector"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "ZoneSystem" && ((MemberReference)val6).Name == "GetZonePos" && ((MemberReference)((ParameterReference)val6.Parameters[0]).ParameterType).FullName == "Vector2i") { text2 = "GetZonePos"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "ZDOMan" && ((MemberReference)val6).Name == "GetPortals") { text2 = "GetPortals"; } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "Humanoid" && ((MemberReference)val6).Name == "IsTeleportable" && val6.Parameters.Count == 0) { text2 = "IsTeleportable"; } if (text2 != null) { val4.OpCode = OpCodes.Call; val4.Operand = func(text2); } if (((MemberReference)((MemberReference)val6).DeclaringType).FullName == "System.Reflection.Assembly" && ((MemberReference)val6).Name == "get_Location") { val4.OpCode = OpCodes.Call; val4.Operand = mod.ImportReference((MethodBase)typeof(ModLoader).GetMethod("OriginalLocation")); } } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } } using MemoryStream memoryStream = new MemoryStream(); val2.Write((Stream)memoryStream); return memoryStream.ToArray(); } finally { if (runtime != null) { ((IDisposable)runtime).Dispose(); } } } finally { ((IDisposable)val2)?.Dispose(); } } private static void FixAttribute(CustomAttribute attr) { //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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (((MemberReference)attr.AttributeType).FullName != "HarmonyLib.HarmonyPatch") { return; } for (int i = 0; i < attr.ConstructorArguments.Count; i++) { CustomAttributeArgument val = attr.ConstructorArguments[i]; if (((CustomAttributeArgument)(ref val)).Value as string == "OnMapRightClick") { Collection constructorArguments = attr.ConstructorArguments; int num = i; val = attr.ConstructorArguments[i]; constructorArguments[num] = new CustomAttributeArgument(((CustomAttributeArgument)(ref val)).Type, (object)"RemovePinUnderPointer"); } } } }