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 HauntedHarpistFix v1.0.1
BepInEx\patchers\HauntedHarpistFix\HauntedHarpistFix.dll
Decompiled 4 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("v0id")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Preloader compatibility patch for Bob123's Haunted Harpist in modern Lethal Company versions.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("HauntedHarpistFix")] [assembly: AssemblyTitle("HauntedHarpistFix")] [assembly: AssemblyVersion("1.0.1.0")] [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 HauntedHarpistFix { public static class Patcher { private static readonly ManualLogSource Logger = Logger.CreateLogSource("HauntedHarpistFix"); public static IEnumerable<string> TargetDLLs { get; } = new string[1] { "LethalCompanyHarpGhost.dll" }; public static void Initialize() { Logger.LogInfo((object)"Preloader initialized. Scanning for LethalCompanyHarpGhost.dll..."); try { string pluginPath = Paths.PluginPath; if (Directory.Exists(pluginPath)) { string[] files = Directory.GetFiles(pluginPath, "LethalCompanyHarpGhost.dll", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { TryPatchFile(files[i]); } } } catch (Exception arg) { Logger.LogError((object)$"Error during scan/patch: {arg}"); } } public static void Patch(AssemblyDefinition assembly) { if (((AssemblyNameReference)assembly.Name).Name == "LethalCompanyHarpGhost") { PatchAssembly(assembly, null); } } public static void Finish() { } public static bool TryPatchFile(string filePath) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003e: 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_004b: Expected O, but got Unknown try { DefaultAssemblyResolver val = new DefaultAssemblyResolver(); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.ManagedPath); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.BepInExAssemblyDirectory); string directoryName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryName)) { ((BaseAssemblyResolver)val).AddSearchDirectory(directoryName); } using MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(filePath)); ReaderParameters val2 = new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val }; AssemblyDefinition val3 = AssemblyDefinition.ReadAssembly((Stream)memoryStream, val2); try { if (PatchAssembly(val3, (IAssemblyResolver?)(object)val)) { string text = filePath + ".orig"; if (!File.Exists(text)) { File.Copy(filePath, text, overwrite: false); } using MemoryStream memoryStream2 = new MemoryStream(); val3.Write((Stream)memoryStream2); File.WriteAllBytes(filePath, memoryStream2.ToArray()); Logger.LogInfo((object)("Successfully patched and updated: " + filePath)); return true; } Logger.LogInfo((object)(filePath + " is already compatible / patched.")); } finally { ((IDisposable)val3)?.Dispose(); } } catch (Exception arg) { Logger.LogError((object)$"Failed to patch {filePath}: {arg}"); } return false; } private static bool PatchAssembly(AssemblyDefinition asm, IAssemblyResolver? resolver) { //IL_002f: 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_003c: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0290: 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_0339: 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) string text = Path.Combine(Paths.ManagedPath, "Assembly-CSharp.dll"); if (!File.Exists(text)) { Logger.LogWarning((object)("Assembly-CSharp.dll not found at " + text)); return false; } ReaderParameters val = new ReaderParameters { AssemblyResolver = resolver }; AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(text, val); try { ModuleDefinition mainModule = val2.MainModule; TypeDefinition type = mainModule.GetType("GameNetcodeStuff.PlayerControllerB"); MethodDefinition val3 = ((type != null) ? ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "HasLineOfSightToPosition" && ((MethodReference)m).Parameters.Count == 5)) : null); TypeDefinition type2 = mainModule.GetType("EnemyAI"); MethodDefinition val4 = ((type2 != null) ? ((IEnumerable<MethodDefinition>)type2.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "EnableEnemyMesh" && ((MethodReference)m).Parameters.Count == 3)) : null); MethodDefinition val5 = ((type2 != null) ? ((IEnumerable<MethodDefinition>)type2.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "ChooseFarthestNodeFromPosition" && ((MethodReference)m).Parameters.Count == 6 && ((MemberReference)((ParameterReference)((MethodReference)m).Parameters[5]).ParameterType).FullName == "System.Int32")) : null); TypeDefinition type3 = mainModule.GetType("EntranceTeleport"); FieldDefinition val6 = ((type3 != null) ? ((IEnumerable<FieldDefinition>)type3.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition f) => ((MemberReference)f).Name == "entrancePoint")) : null); if (val3 == null || val4 == null || val5 == null || val6 == null) { Logger.LogWarning((object)"Failed to resolve required modern target symbols from Assembly-CSharp.dll"); return false; } ModuleDefinition mainModule2 = asm.MainModule; MethodReference operand = mainModule2.ImportReference((MethodReference)(object)val3); MethodReference operand2 = mainModule2.ImportReference((MethodReference)(object)val4); MethodReference operand3 = mainModule2.ImportReference((MethodReference)(object)val5); FieldReference operand4 = mainModule2.ImportReference((FieldReference)(object)val6); int num = 0; Enumerator<TypeDefinition> enumerator = mainModule2.Types.GetEnumerator(); try { while (enumerator.MoveNext()) { Enumerator<MethodDefinition> enumerator2 = enumerator.Current.Methods.GetEnumerator(); try { while (enumerator2.MoveNext()) { MethodDefinition current = enumerator2.Current; if (!current.HasBody) { continue; } ILProcessor iLProcessor = current.Body.GetILProcessor(); Instruction[] array = current.Body.Instructions.ToArray(); for (int num2 = 0; num2 < array.Length; num2++) { Instruction val7 = array[num2]; if (val7.Operand == null) { continue; } string? text2 = val7.Operand.ToString(); if (text2.Contains("HasLineOfSightToPosition")) { object operand5 = val7.Operand; MethodReference val8 = (MethodReference)((operand5 is MethodReference) ? operand5 : null); if (val8 != null && val8.Parameters.Count == 4) { Instruction val9 = Instruction.Create(OpCodes.Ldc_I4_M1); iLProcessor.InsertBefore(val7, val9); val7.Operand = operand; num++; } } if (text2.Contains("EnableEnemyMesh")) { object operand6 = val7.Operand; MethodReference val10 = (MethodReference)((operand6 is MethodReference) ? operand6 : null); if (val10 != null && val10.Parameters.Count == 2) { Instruction val11 = Instruction.Create(OpCodes.Ldc_I4_0); iLProcessor.InsertBefore(val7, val11); val7.Operand = operand2; num++; } } if (text2.Contains("EntranceTeleport::exitPoint")) { val7.Operand = operand4; num++; } if (!text2.Contains("ChooseFarthestNodeFromPosition")) { continue; } object operand7 = val7.Operand; MethodReference val12 = (MethodReference)((operand7 is MethodReference) ? operand7 : null); if (val12 != null && val12.Parameters.Count == 6 && ((MemberReference)((ParameterReference)val12.Parameters[5]).ParameterType).FullName == "System.Boolean") { if (num2 > 0 && ((object)array[num2 - 1].OpCode/*cast due to .constrained prefix*/).ToString().StartsWith("ldc.i4")) { array[num2 - 1].OpCode = OpCodes.Ldc_I4_M1; array[num2 - 1].Operand = null; } val7.Operand = operand3; num++; } } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return num > 0; } finally { ((IDisposable)val2)?.Dispose(); } } } }