Decompiled source of Valheim10 CompatPack v0.1.1

BepInEx/patchers/OliveValheim10Compat/OliveValheim10Compat.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.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<string> 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<TypeDefinition>)mainModule.Types).Any((TypeDefinition t) => ((MemberReference)t).Name == "OliveCompatApplied"))
		{
			return;
		}
		TypeDefinition val2 = Type(mainModule, "ZRoutedRpc");
		FieldDefinition val3 = ((IEnumerable<FieldDefinition>)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<MethodDefinition>)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<MethodDefinition>)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<MethodDefinition>)Type(mainModule, "Player").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ActivateGuardianPower");
		int num3 = 0;
		Enumerator<Instruction> 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<MethodDefinition>)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<MethodDefinition>)Type(mainModule, "InventoryGui").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "DoCrafting");
		Enumerator<Instruction> 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<MethodDefinition>)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<MethodDefinition>)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<ParameterDefinition> 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<MethodDefinition>)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<int, ParameterDefinition> dictionary = new Dictionary<int, ParameterDefinition>();
		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<ParameterDefinition> 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<VariableDefinition> 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<Instruction, Instruction> map = new Dictionary<Instruction, Instruction>();
		Enumerator<Instruction> 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<Instruction> 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<ExceptionHandler> 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<string, Assembly> Loaded = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);

	private static readonly Dictionary<Assembly, string> Locations = new Dictionary<Assembly, string>();

	private static readonly Dictionary<string, string> Hashes = new Dictionary<string, string>(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<string, MethodReference> func = (string name) => mod.ImportReference((MethodReference)(object)((IEnumerable<MethodDefinition>)runtime.MainModule.GetType("OliveRuntimeBridge").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == name));
				foreach (TypeDefinition type in mod.GetTypes())
				{
					Enumerator<CustomAttribute> enumerator2 = type.CustomAttributes.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							CustomAttribute current2 = enumerator2.Current;
							FixAttribute(current2);
						}
					}
					finally
					{
						((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
					Enumerator<MethodDefinition> enumerator3 = type.Methods.GetEnumerator();
					try
					{
						while (enumerator3.MoveNext())
						{
							MethodDefinition current3 = enumerator3.Current;
							Enumerator<CustomAttribute> 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<ParameterDefinition> 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<ParameterDefinition>)((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<CustomAttributeArgument> constructorArguments = attr.ConstructorArguments;
				int num = i;
				val = attr.ConstructorArguments[i];
				constructorArguments[num] = new CustomAttributeArgument(((CustomAttributeArgument)(ref val)).Type, (object)"RemovePinUnderPointer");
			}
		}
	}
}

BepInEx/plugins/OliveValheim10Compat/OliveRuntimeBridge.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;

[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 OliveRuntimeBridge
{
	public static Biome SectorBiome(BiomeSector sector)
	{
		//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_000a: Unknown result type (might be due to invalid IL or missing references)
		return sector.Biome;
	}

	public static void Changed(Inventory inventory)
	{
		inventory.Changed(false, false);
	}

	public static ItemData AddItem(Inventory inventory, string name, int stack, int quality, int variant, long crafter, string crafterName, bool cheated)
	{
		return inventory.AddItem(name, stack, quality, variant, crafter, crafterName, cheated, false);
	}

	public static void SpawnItem(CookingStation station, string name, int slot, Vector3 point, bool cheated)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		station.SpawnItem(name, slot, point, cheated);
	}

	public static Vector2i GetSector(ZDO zdo)
	{
		//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_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Vector2s sector = zdo.GetSector();
		return new Vector2i((int)sector.x, (int)sector.y);
	}

	public static Vector3 GetZonePos(Vector2i s)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0019: 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)
		return ZoneSystem.GetZonePos(checked(new Vector2s((short)s.x, (short)s.y)));
	}

	public static List<ZDO> GetPortals(ZDOMan manager)
	{
		return manager.GetPortals().Values.SelectMany((List<ZDO> v) => v).Distinct().ToList();
	}

	public static Dictionary<string, float> EnemyStats(PlayerProfile profile)
	{
		return profile.m_playerStats[0].m_enemyStats[0];
	}

	public static Color NoForest(Minimap map)
	{
		//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)
		return Minimap.s_noForestColor;
	}

	public static bool IsTeleportable(Humanoid humanoid)
	{
		return humanoid.IsTeleportable(false);
	}

	public static bool FindZdos(ZDOMan manager, List<string> prefabs, List<ZDO> zdos, ref int index)
	{
		HashSet<int> hashSet = new HashSet<int>(prefabs.Select((string p) => StringExtensionMethods.GetStableHashCode(p)));
		List<ZDO>[] objectsBySector = manager.m_objectsBySector;
		int num = Math.Min(objectsBySector.Length, index + 401);
		while (index < num)
		{
			if (objectsBySector[index] != null)
			{
				foreach (ZDO item in objectsBySector[index])
				{
					if (item.IsValid() && hashSet.Contains(item.GetPrefab()) && !zdos.Contains(item))
					{
						zdos.Add(item);
					}
				}
			}
			index++;
		}
		if (index < objectsBySector.Length)
		{
			return false;
		}
		foreach (ZDO portal in GetPortals(manager))
		{
			if (portal.IsValid() && hashSet.Contains(portal.GetPrefab()) && !zdos.Contains(portal))
			{
				zdos.Add(portal);
			}
		}
		zdos.RemoveAll((ZDO z) => !z.IsValid());
		return true;
	}
}