Decompiled source of Deep North Compat v1.0.0

patchers/MistookenCompat.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Mono.Cecil;
using Mono.Cecil.Cil;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
public static class MistookenCompatPatcher
{
	private static readonly string[][] Shims = new string[2][]
	{
		new string[6] { "Character", "Message", "MessageHud/MessageType", "System.String", "System.Int32", "UnityEngine.Sprite" },
		new string[6] { "SEMan", "AddStatusEffect", "System.Int32", "System.Boolean", "System.Int32", "System.Single" }
	};

	public static IEnumerable<string> TargetDLLs
	{
		get
		{
			yield return "assembly_valheim.dll";
		}
	}

	public static void Patch(AssemblyDefinition assembly)
	{
		string[][] shims = Shims;
		foreach (string[] array in shims)
		{
			try
			{
				AddForwardingOverload(assembly.MainModule, array[0], array[1], array.Skip(2).ToArray());
			}
			catch (Exception)
			{
			}
		}
	}

	private static bool ParamsMatch(MethodDefinition m, string[] oldTypes, int count)
	{
		if (((MethodReference)m).Parameters.Count != count)
		{
			return false;
		}
		for (int i = 0; i < oldTypes.Length && i < count; i++)
		{
			if (((MemberReference)((ParameterReference)((MethodReference)m).Parameters[i]).ParameterType).FullName != oldTypes[i])
			{
				return false;
			}
		}
		return true;
	}

	private static void AddForwardingOverload(ModuleDefinition module, string typeName, string methodName, string[] oldTypes)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition type = module.GetType(typeName);
		if (type == null || ((IEnumerable<MethodDefinition>)type.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == methodName && ParamsMatch(m, oldTypes, oldTypes.Length)))
		{
			return;
		}
		MethodDefinition val = ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == methodName && ((MethodReference)m).Parameters.Count > oldTypes.Length && ParamsMatch(m, oldTypes, ((MethodReference)m).Parameters.Count)));
		if (val != null)
		{
			MethodAttributes val2 = (MethodAttributes)134;
			if (val.IsStatic)
			{
				val2 = (MethodAttributes)(ushort)(val2 | 0x10);
			}
			MethodDefinition val3 = new MethodDefinition(methodName, val2, ((MethodReference)val).ReturnType);
			((MethodReference)val3).HasThis = !val.IsStatic;
			for (int num = 0; num < oldTypes.Length; num++)
			{
				((MethodReference)val3).Parameters.Add(new ParameterDefinition(((ParameterReference)((MethodReference)val).Parameters[num]).Name, (ParameterAttributes)0, ((ParameterReference)((MethodReference)val).Parameters[num]).ParameterType));
			}
			val3.Body.InitLocals = true;
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			if (!val.IsStatic)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
			}
			for (int num2 = 0; num2 < oldTypes.Length; num2++)
			{
				iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val3).Parameters[num2]);
			}
			for (int num3 = oldTypes.Length; num3 < ((MethodReference)val).Parameters.Count; num3++)
			{
				EmitDefault(val3, iLProcessor, ((MethodReference)val).Parameters[num3]);
			}
			iLProcessor.Emit((!val.IsStatic && val.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Ret);
			type.Methods.Add(val3);
		}
	}

	private static void EmitDefault(MethodDefinition shim, ILProcessor il, ParameterDefinition p)
	{
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: 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_003e: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (p.HasConstant && p.Constant != null)
		{
			object constant = p.Constant;
			if (constant is bool)
			{
				il.Emit((!(bool)constant) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
				return;
			}
			if (constant is int)
			{
				il.Emit(OpCodes.Ldc_I4, (int)constant);
				return;
			}
			if (constant is short)
			{
				il.Emit(OpCodes.Ldc_I4, (int)(short)constant);
				return;
			}
			if (constant is byte)
			{
				il.Emit(OpCodes.Ldc_I4, (int)(byte)constant);
				return;
			}
			if (constant is float)
			{
				il.Emit(OpCodes.Ldc_R4, (float)constant);
				return;
			}
		}
		TypeDefinition val = ((ParameterReference)p).ParameterType.Resolve();
		if (val != null && ((TypeReference)val).IsValueType)
		{
			VariableDefinition val2 = new VariableDefinition(((ParameterReference)p).ParameterType);
			shim.Body.Variables.Add(val2);
			il.Emit(OpCodes.Ldloca, val2);
			il.Emit(OpCodes.Initobj, ((ParameterReference)p).ParameterType);
			il.Emit(OpCodes.Ldloc, val2);
		}
		else
		{
			il.Emit(OpCodes.Ldnull);
		}
	}
}