Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Warfare Valheim 1 0 Compatibility Fix v1.0.1
BepInEx/patchers/Warfare_Valheim_1_0_Compatibility_Fix.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using BepInEx; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ADARC.WarfareCompatibility; public static class WarfareCompatibilityPatcher { private const string SupportedAssemblyName = "Warfare"; private const string SupportedAssemblyVersion = "1.8.9.0"; private const string OriginalSha256 = "DF6EBC8616C9D239B8FA4A22875D45984962F87B4AECA88F982895707B4D9F5A"; private const string PatchedSha256 = "DA26B3E9E74BEFD9FEDBAE5E2C202923405544AD513B74D3A0353211318A8339"; public static IEnumerable<string> TargetDLLs => new string[0]; public static void Initialize() { string pluginPath = Paths.PluginPath; if (!Directory.Exists(pluginPath)) { throw new InvalidOperationException("The active BepInEx profile plugin directory was not found. Warfare was not modified."); } string[] files = Directory.GetFiles(pluginPath, "Warfare.dll", SearchOption.AllDirectories); if (files.Length != 1) { throw new InvalidOperationException("Expected exactly one installed Warfare.dll but found " + files.Length + ". No file was modified."); } string text = files[0]; string text2 = Sha256(text); if (text2 == "DA26B3E9E74BEFD9FEDBAE5E2C202923405544AD513B74D3A0353211318A8339") { Console.WriteLine("[Warfare 1.0 Compatibility Fix] Verified existing patched Warfare 1.8.9 DLL."); return; } if (text2 != "DF6EBC8616C9D239B8FA4A22875D45984962F87B4AECA88F982895707B4D9F5A") { throw new InvalidOperationException("Installed Warfare.dll is not the verified original Warfare 1.8.9 build. Expected SHA-256 DF6EBC8616C9D239B8FA4A22875D45984962F87B4AECA88F982895707B4D9F5A but found " + text2 + ". No file was modified."); } string text3 = text + ".before-valheim-1.0-fix"; if (!File.Exists(text3)) { File.Copy(text, text3, overwrite: false); } if (Sha256(text3) != "DF6EBC8616C9D239B8FA4A22875D45984962F87B4AECA88F982895707B4D9F5A") { throw new InvalidOperationException("The existing Warfare backup is not an exact original. No file was modified."); } string text4 = text + ".valheim-1.0-fix.tmp"; if (File.Exists(text4)) { File.Delete(text4); } try { AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(text); try { Patch(ref assembly); assembly.Write(text4); } finally { assembly.Dispose(); } string text5 = Sha256(text4); if (text5 != "DA26B3E9E74BEFD9FEDBAE5E2C202923405544AD513B74D3A0353211318A8339") { throw new InvalidOperationException("Patched Warfare output failed its exact SHA-256 check. Expected DA26B3E9E74BEFD9FEDBAE5E2C202923405544AD513B74D3A0353211318A8339 but found " + text5 + ". The installed DLL was left unchanged."); } File.Replace(text4, text, null); if (Sha256(text) != "DA26B3E9E74BEFD9FEDBAE5E2C202923405544AD513B74D3A0353211318A8339") { throw new InvalidOperationException("Warfare replacement did not verify after writing."); } Console.WriteLine("[Warfare 1.0 Compatibility Fix] Installed and verified the guarded Warfare 1.8.9 repair. Original backup: " + text3); } finally { if (File.Exists(text4)) { File.Delete(text4); } } } public static void Patch(ref AssemblyDefinition assembly) { //IL_0097: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Expected O, but got Unknown //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Expected O, but got Unknown //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_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Expected O, but got Unknown //IL_050a: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Expected O, but got Unknown if (assembly == null || ((AssemblyNameReference)assembly.Name).Name != "Warfare" || ((AssemblyNameReference)assembly.Name).Version.ToString() != "1.8.9.0") { throw new InvalidOperationException("Warfare 1.0 Compatibility Fix supports only the original Warfare 1.8.9 assembly. The installed Warfare DLL was not modified."); } List<Instruction> list = new List<Instruction>(); List<Instruction> list2 = new List<Instruction>(); List<Instruction> list3 = new List<Instruction>(); List<Instruction> list4 = new List<Instruction>(); List<Instruction> list5 = new List<Instruction>(); Dictionary<Instruction, MethodDefinition> dictionary = new Dictionary<Instruction, MethodDefinition>(); foreach (TypeDefinition item in AllTypes((IEnumerable<TypeDefinition>)assembly.MainModule.Types)) { Enumerator<MethodDefinition> enumerator2 = item.Methods.GetEnumerator(); try { while (enumerator2.MoveNext()) { MethodDefinition current2 = enumerator2.Current; if (!current2.HasBody) { continue; } Enumerator<Instruction> enumerator3 = current2.Body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current3 = enumerator3.Current; dictionary[current3] = current2; object operand = current3.Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); if (current3.OpCode == OpCodes.Ldsfld && val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "ZRoutedRpc" && ((MemberReference)val).Name == "Everybody" && ((MemberReference)val.FieldType).FullName == "System.Int64") { list.Add(current3); continue; } if (current3.OpCode == OpCodes.Ldfld && val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == "PieceTable" && ((MemberReference)val).Name == "m_availablePieces") { list5.Add(current3); continue; } object operand2 = current3.Operand; MethodReference val2 = (MethodReference)((operand2 is MethodReference) ? operand2 : null); if (val2 != null) { if ((current3.OpCode == OpCodes.Call || current3.OpCode == OpCodes.Callvirt) && IsOldStatusEffectCall(val2)) { list2.Add(current3); } else if ((current3.OpCode == OpCodes.Call || current3.OpCode == OpCodes.Callvirt) && IsOldCharacterMessage(val2)) { list3.Add(current3); } else if (current3.OpCode == OpCodes.Newobj && IsOldConsoleConstructor(val2)) { list4.Add(current3); } } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } RequireCount("ZRoutedRpc.Everybody references", list.Count, 4); RequireCount("SEMan.AddStatusEffect calls", list2.Count, 33); RequireCount("Character.Message calls", list3.Count, 1); RequireCount("Terminal.ConsoleCommand constructors", list4.Count, 1); RequireCount("PieceTable.m_availablePieces references", list5.Count, 5); foreach (Instruction item2 in list) { item2.OpCode = OpCodes.Ldc_I8; item2.Operand = 0L; } foreach (Instruction item3 in list5) { FieldReference val3 = (FieldReference)item3.Operand; item3.Operand = (object)new FieldReference("m_availablePiecesByCategory", val3.FieldType, ((MemberReference)val3).DeclaringType); } foreach (Instruction item4 in list2) { MethodDefinition val4 = dictionary[item4]; ILProcessor iLProcessor = val4.Body.GetILProcessor(); iLProcessor.InsertBefore(item4, iLProcessor.Create(OpCodes.Ldc_I4_0)); iLProcessor.InsertBefore(item4, iLProcessor.Create(OpCodes.Conv_I2)); item4.Operand = AppendParameter((MethodReference)item4.Operand, assembly.MainModule.TypeSystem.Int16); } foreach (Instruction item5 in list3) { MethodDefinition val5 = dictionary[item5]; ILProcessor iLProcessor2 = val5.Body.GetILProcessor(); iLProcessor2.InsertBefore(item5, iLProcessor2.Create(OpCodes.Ldc_I4_0)); item5.Operand = AppendParameter((MethodReference)item5.Operand, assembly.MainModule.TypeSystem.Boolean); } foreach (Instruction item6 in list4) { MethodDefinition val6 = dictionary[item6]; ILProcessor iLProcessor3 = val6.Body.GetILProcessor(); Instruction val7 = item6; for (int i = 0; i < 4; i++) { val7 = val7.Previous; } if (val7 == null || val7.OpCode != OpCodes.Ldnull) { throw new InvalidOperationException("The Warfare console-command call shape was not recognized."); } iLProcessor3.InsertBefore(val7, iLProcessor3.Create(OpCodes.Ldc_I4_0)); item6.Operand = InsertParameter((MethodReference)item6.Operand, 8, assembly.MainModule.TypeSystem.Boolean); } Console.WriteLine("[Warfare 1.0 Compatibility Fix] Applied 44 guarded method repairs to original Warfare 1.8.9."); } private static IEnumerable<TypeDefinition> AllTypes(IEnumerable<TypeDefinition> roots) { foreach (TypeDefinition type in roots) { yield return type; foreach (TypeDefinition item in AllTypes((IEnumerable<TypeDefinition>)type.NestedTypes)) { yield return item; } } } private static bool IsOldStatusEffectCall(MethodReference method) { if (((MemberReference)((MemberReference)method).DeclaringType).FullName == "SEMan" && ((MemberReference)method).Name == "AddStatusEffect") { return HasParameters(method, "System.Int32", "System.Boolean", "System.Int32", "System.Single"); } return false; } private static bool IsOldCharacterMessage(MethodReference method) { if (((MemberReference)((MemberReference)method).DeclaringType).FullName == "Character" && ((MemberReference)method).Name == "Message") { return HasParameters(method, "MessageHud/MessageType", "System.String", "System.Int32", "UnityEngine.Sprite"); } return false; } private static bool IsOldConsoleConstructor(MethodReference method) { if (((MemberReference)((MemberReference)method).DeclaringType).FullName == "Terminal/ConsoleCommand" && ((MemberReference)method).Name == ".ctor") { return HasParameters(method, "System.String", "System.String", "Terminal/ConsoleEvent", "System.Boolean", "System.Boolean", "System.Boolean", "System.Boolean", "System.Boolean", "Terminal/ConsoleOptionsFetcher", "System.Boolean", "System.Boolean", "System.Boolean"); } return false; } private static bool HasParameters(MethodReference method, params string[] types) { if (method.Parameters.Count != types.Length) { return false; } for (int i = 0; i < types.Length; i++) { if (((MemberReference)((ParameterReference)method.Parameters[i]).ParameterType).FullName != types[i]) { return false; } } return true; } private static MethodReference AppendParameter(MethodReference source, TypeReference parameterType) { return InsertParameter(source, source.Parameters.Count, parameterType); } private static MethodReference InsertParameter(MethodReference source, int index, TypeReference parameterType) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown MethodReference val = new MethodReference(((MemberReference)source).Name, source.ReturnType, ((MemberReference)source).DeclaringType); val.HasThis = source.HasThis; val.ExplicitThis = source.ExplicitThis; val.CallingConvention = source.CallingConvention; MethodReference val2 = val; for (int i = 0; i <= source.Parameters.Count; i++) { if (i == index) { val2.Parameters.Add(new ParameterDefinition(parameterType)); } if (i < source.Parameters.Count) { val2.Parameters.Add(new ParameterDefinition(((ParameterReference)source.Parameters[i]).ParameterType)); } } return val2; } private static void RequireCount(string repair, int actual, int expected) { if (actual != expected) { throw new InvalidOperationException("Warfare 1.0 Compatibility Fix expected " + expected + " " + repair + " in original Warfare 1.8.9 but found " + actual + ". Nothing was patched."); } } private static string Sha256(string path) { using FileStream inputStream = File.OpenRead(path); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", ""); } }