Decompiled source of EvuMiscCompat v0.2.0

EvuMiscCompat.Core.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("evu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 imevul")]
[assembly: AssemblyDescription("Compatibility fixes for other Valheim mods.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+ac059ef239dd58a46c4673283cd7d6ce2d5f5dbe")]
[assembly: AssemblyProduct("EvuMiscCompat")]
[assembly: AssemblyTitle("EvuMiscCompat.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvuMods/EvuMiscCompat")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 EvuMiscCompat.Core
{
	public enum IlOpKind
	{
		Other,
		Ldarg0,
		Ldarg1,
		Ldarg2,
		LdcI4_3,
		BneUn,
		Call,
		Brtrue
	}
	public readonly struct IlOp : IEquatable<IlOp>
	{
		public IlOpKind Kind { get; }

		public string? Name { get; }

		public IlOp(IlOpKind kind, string? name = null)
		{
			Kind = kind;
			Name = name;
		}

		public bool Equals(IlOp other)
		{
			if (Kind == other.Kind)
			{
				return Name == other.Name;
			}
			return false;
		}

		public override bool Equals(object? obj)
		{
			if (obj is IlOp other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return ((int)Kind * 397) ^ (Name?.GetHashCode() ?? 0);
		}
	}
	public static class DualWieldWindow
	{
		public const string OffhandMethod = "CheckDualOneHandedWeaponEquip";

		public static List<IlOp> Repair(IReadOnlyList<IlOp> code)
		{
			List<IlOp> list = new List<IlOp>(code.Count + 5);
			for (int i = 0; i < code.Count; i++)
			{
				list.Add(code[i]);
				if (IsOneHandedBranch(code, i) && !HasOffhandFallthrough(code, i))
				{
					string name = code[i].Name;
					list.Add(new IlOp(IlOpKind.Ldarg0));
					list.Add(new IlOp(IlOpKind.Ldarg1));
					list.Add(new IlOp(IlOpKind.Ldarg2));
					list.Add(new IlOp(IlOpKind.Call, "CheckDualOneHandedWeaponEquip"));
					list.Add(new IlOp(IlOpKind.Brtrue, name));
				}
			}
			return list;
		}

		private static bool IsOneHandedBranch(IReadOnlyList<IlOp> code, int index)
		{
			if (code[index].Kind != IlOpKind.BneUn)
			{
				return false;
			}
			if (index < 1 || code[index - 1].Kind != IlOpKind.LdcI4_3)
			{
				return false;
			}
			if (!IsVanillaWindow(code, index))
			{
				return IsTrinketsWindow(code, index);
			}
			return true;
		}

		private static bool IsVanillaWindow(IReadOnlyList<IlOp> code, int branch)
		{
			if (branch >= 4 && code[branch - 4].Kind == IlOpKind.Ldarg1 && code[branch - 3].Kind == IlOpKind.Other)
			{
				return code[branch - 2].Kind == IlOpKind.Other;
			}
			return false;
		}

		private static bool IsTrinketsWindow(IReadOnlyList<IlOp> code, int branch)
		{
			if (branch >= 7 && code[branch - 7].Kind == IlOpKind.Ldarg1 && code[branch - 6].Kind == IlOpKind.Other && code[branch - 5].Kind == IlOpKind.Other && code[branch - 4].Kind == IlOpKind.Ldarg0 && code[branch - 3].Kind == IlOpKind.Ldarg1)
			{
				return code[branch - 2].Kind == IlOpKind.Call;
			}
			return false;
		}

		private static bool HasOffhandFallthrough(IReadOnlyList<IlOp> code, int branch)
		{
			if (branch + 5 >= code.Count)
			{
				return false;
			}
			if (code[branch + 1].Kind == IlOpKind.Ldarg0 && code[branch + 2].Kind == IlOpKind.Ldarg1 && code[branch + 3].Kind == IlOpKind.Ldarg2 && code[branch + 4].Kind == IlOpKind.Call && code[branch + 4].Name == "CheckDualOneHandedWeaponEquip" && code[branch + 5].Kind == IlOpKind.Brtrue)
			{
				return code[branch + 5].Name == code[branch].Name;
			}
			return false;
		}
	}
}

EvuMiscCompat.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using EvuMiscCompat.Core;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("evu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 imevul")]
[assembly: AssemblyDescription("Compatibility fixes for other Valheim mods.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+ac059ef239dd58a46c4673283cd7d6ce2d5f5dbe")]
[assembly: AssemblyProduct("EvuMiscCompat")]
[assembly: AssemblyTitle("EvuMiscCompat")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvuMods/EvuMiscCompat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 EvuMiscCompat
{
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class DualWieldEquipRepair
	{
		[HarmonyTranspiler]
		[HarmonyPriority(0)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo methodInfo = FindOffhand();
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			if (methodInfo == null)
			{
				return list;
			}
			List<IlOp> list2 = new List<IlOp>(list.Count);
			for (int i = 0; i < list.Count; i++)
			{
				list2.Add(Map(list[i]));
			}
			List<IlOp> list3 = DualWieldWindow.Repair((IReadOnlyList<IlOp>)list2);
			if (list3.Count == list2.Count)
			{
				return list;
			}
			List<CodeInstruction> list4 = new List<CodeInstruction>(list3.Count);
			object branch = null;
			int num = 0;
			for (int j = 0; j < list3.Count; j++)
			{
				if (num < list.Count)
				{
					IlOp val = Map(list[num]);
					if (((IlOp)(ref val)).Equals(list3[j]))
					{
						list4.Add(list[num]);
						if (list[num].opcode == OpCodes.Bne_Un)
						{
							branch = list[num].operand;
						}
						num++;
						continue;
					}
				}
				list4.Add(Emit(list3[j], branch, methodInfo));
			}
			if (num != list.Count)
			{
				Plugin.Log.LogWarning((object)"Dual Wield offhand repair did not consume Humanoid.EquipItem. Left the method unchanged.");
				return list;
			}
			Plugin.Log.LogInfo((object)"Restored Dual Wield offhand equip on Humanoid.EquipItem.");
			return list4;
		}

		private static MethodInfo? FindOffhand()
		{
			Type type = AccessTools.TypeByName("DualWield.DualWield");
			if (type == null)
			{
				return null;
			}
			Type type2 = AccessTools.Inner(type, "Patch_Humanoid_EquipItem");
			if (type2 == null)
			{
				return null;
			}
			return AccessTools.DeclaredMethod(type2, "CheckDualOneHandedWeaponEquip", (Type[])null, (Type[])null);
		}

		private static IlOp Map(CodeInstruction instruction)
		{
			//IL_0014: 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_0048: 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_0086: 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)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (instruction.opcode == OpCodes.Ldarg_0)
			{
				return new IlOp((IlOpKind)1, (string)null);
			}
			if (instruction.opcode == OpCodes.Ldarg_1)
			{
				return new IlOp((IlOpKind)2, (string)null);
			}
			if (instruction.opcode == OpCodes.Ldarg_2)
			{
				return new IlOp((IlOpKind)3, (string)null);
			}
			if (instruction.opcode == OpCodes.Ldc_I4_3)
			{
				return new IlOp((IlOpKind)4, (string)null);
			}
			if (instruction.opcode == OpCodes.Bne_Un)
			{
				return new IlOp((IlOpKind)5, OperandName(instruction.operand));
			}
			if (instruction.opcode == OpCodes.Brtrue)
			{
				return new IlOp((IlOpKind)7, OperandName(instruction.operand));
			}
			if (instruction.opcode == OpCodes.Call && instruction.operand is MethodInfo methodInfo)
			{
				return new IlOp((IlOpKind)6, methodInfo.Name);
			}
			return new IlOp((IlOpKind)0, (string)null);
		}

		private static CodeInstruction Emit(IlOp op, object? branch, MethodInfo offhand)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected I4, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			IlOpKind kind = ((IlOp)(ref op)).Kind;
			return (CodeInstruction)((kind - 1) switch
			{
				0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 
				1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 
				2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 
				5 => (object)new CodeInstruction(OpCodes.Call, (object)offhand), 
				6 => (object)new CodeInstruction(OpCodes.Brtrue, branch), 
				_ => (object)new CodeInstruction(OpCodes.Nop, (object)null), 
			});
		}

		private static string? OperandName(object? operand)
		{
			return operand?.ToString();
		}
	}
	[BepInPlugin("evu.evumisccompat", "EvuMiscCompat", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "evu.evumisccompat");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"EvuMiscCompat loaded.");
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "evu.evumisccompat";

		public const string Name = "EvuMiscCompat";

		public const string Version = "0.2.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}