using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; 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: AssemblyTitle("ClassLibrary1")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ClassLibrary1")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ced08244-5661-4dfb-948a-0dad7d38c0a3")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace SurfacedFixPatcher; public static class SurfacedPatcher { public static IEnumerable TargetDLLs { get; } = Array.Empty(); public static void Patch(AssemblyDefinition assembly) { } public static void Initialize() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown try { string[] files = Directory.GetFiles(Paths.PluginPath, "Surfaced.dll", SearchOption.AllDirectories); if (files.Length == 0) { Console.WriteLine("[SurfacedPatcher] Nie znaleziono Surfaced.dll"); return; } string text = files[0]; string text2 = text + ".bak"; string text3 = text + ".patched"; if (!File.Exists(text2)) { File.Copy(text, text2, overwrite: true); Console.WriteLine("[SurfacedPatcher] Utworzono backup: " + Path.GetFileName(text2)); } DefaultAssemblyResolver val = new DefaultAssemblyResolver(); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.ManagedPath); ((BaseAssemblyResolver)val).AddSearchDirectory(Path.GetDirectoryName(text)); string[] directories = Directory.GetDirectories(Paths.PluginPath, "*", SearchOption.AllDirectories); foreach (string text4 in directories) { ((BaseAssemblyResolver)val).AddSearchDirectory(text4); } ReaderParameters val2 = new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val, ReadWrite = false, InMemory = true }; bool flag = false; AssemblyDefinition val3 = AssemblyDefinition.ReadAssembly(text, val2); try { MethodDefinition helperMethod = EnsureBellCrabStub(val3.MainModule); foreach (TypeDefinition item in val3.MainModule.GetTypes().ToList()) { flag |= FixTargetClosestPlayer(item); flag |= FixPlayerIsTargetable(item); flag |= FixKillPlayer(item); flag |= FixBellCrabDropCall(item, helperMethod); } if (flag) { if (File.Exists(text3)) { File.Delete(text3); } val3.Write(text3); } } finally { ((IDisposable)val3)?.Dispose(); } if (flag && File.Exists(text3)) { File.Copy(text3, text, overwrite: true); File.Delete(text3); Console.WriteLine("[SurfacedPatcher] Surfaced.dll zostal spatchowany pomyslnie."); } else { Console.WriteLine("[SurfacedPatcher] Nie znaleziono nowych rzeczy do poprawy albo plik jest juz poprawiony."); } } catch (Exception ex) { Console.WriteLine("[SurfacedPatcher] BLAD: " + ex); } } private static bool FixTargetClosestPlayer(TypeDefinition type) { //IL_000a: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown bool result = false; Enumerator enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; if (!current.HasBody) { continue; } ILProcessor iLProcessor = current.Body.GetILProcessor(); List list = ((IEnumerable)current.Body.Instructions).ToList(); foreach (Instruction item in list) { if (IsCall(item)) { object operand = item.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && ((MemberReference)val).Name == "TargetClosestPlayer" && val.Parameters.Count == 3) { iLProcessor.InsertBefore(item, Instruction.Create(OpCodes.Ldc_I4_0)); iLProcessor.InsertBefore(item, Instruction.Create(OpCodes.Ldc_I4_0)); iLProcessor.InsertBefore(item, Instruction.Create(OpCodes.Ldc_I4_1)); MethodReference val2 = new MethodReference("TargetClosestPlayer", ((MemberReference)type).Module.TypeSystem.Boolean, ((MemberReference)val).DeclaringType) { HasThis = true }; val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Single)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Single)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); item.Operand = ((MemberReference)type).Module.ImportReference(val2); result = true; Console.WriteLine("[SurfacedPatcher] Fix TargetClosestPlayer -> " + ((MemberReference)type).FullName + "::" + ((MemberReference)current).Name); } } } } } finally { ((IDisposable)enumerator).Dispose(); } return result; } private static bool FixPlayerIsTargetable(TypeDefinition type) { //IL_000a: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown bool result = false; Enumerator enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; if (!current.HasBody) { continue; } ILProcessor iLProcessor = current.Body.GetILProcessor(); List list = ((IEnumerable)current.Body.Instructions).ToList(); foreach (Instruction item in list) { if (IsCall(item)) { object operand = item.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && ((MemberReference)val).Name == "PlayerIsTargetable" && val.Parameters.Count == 3) { iLProcessor.InsertBefore(item, Instruction.Create(OpCodes.Ldc_I4_0)); MethodReference val2 = new MethodReference("PlayerIsTargetable", ((MemberReference)type).Module.TypeSystem.Boolean, ((MemberReference)val).DeclaringType) { HasThis = true }; val2.Parameters.Add(new ParameterDefinition(((ParameterReference)val.Parameters[0]).ParameterType)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); item.Operand = ((MemberReference)type).Module.ImportReference(val2); result = true; Console.WriteLine("[SurfacedPatcher] Fix PlayerIsTargetable -> " + ((MemberReference)type).FullName + "::" + ((MemberReference)current).Name); } } } } } finally { ((IDisposable)enumerator).Dispose(); } return result; } private static bool FixKillPlayer(TypeDefinition type) { //IL_000a: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown bool result = false; Enumerator enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; if (!current.HasBody) { continue; } ILProcessor iLProcessor = current.Body.GetILProcessor(); List list = ((IEnumerable)current.Body.Instructions).ToList(); foreach (Instruction item in list) { if (IsCall(item)) { object operand = item.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && ((MemberReference)val).Name == "KillPlayer" && val.Parameters.Count == 5) { iLProcessor.InsertBefore(item, Instruction.Create(OpCodes.Ldc_I4_0)); MethodReference val2 = new MethodReference("KillPlayer", ((MemberReference)type).Module.TypeSystem.Void, ((MemberReference)val).DeclaringType) { HasThis = true }; val2.Parameters.Add(new ParameterDefinition(((ParameterReference)val.Parameters[0]).ParameterType)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); val2.Parameters.Add(new ParameterDefinition(((ParameterReference)val.Parameters[2]).ParameterType)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Int32)); val2.Parameters.Add(new ParameterDefinition(((ParameterReference)val.Parameters[4]).ParameterType)); val2.Parameters.Add(new ParameterDefinition(((MemberReference)type).Module.TypeSystem.Boolean)); item.Operand = ((MemberReference)type).Module.ImportReference(val2); result = true; Console.WriteLine("[SurfacedPatcher] Fix KillPlayer(5->6) -> " + ((MemberReference)type).FullName + "::" + ((MemberReference)current).Name); } } } } } finally { ((IDisposable)enumerator).Dispose(); } return result; } private static bool FixBellCrabDropCall(TypeDefinition type, MethodDefinition helperMethod) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) bool result = false; if (!((MemberReference)type).FullName.Contains("BellCrabAI")) { return false; } Enumerator enumerator = type.Methods.GetEnumerator(); try { while (enumerator.MoveNext()) { MethodDefinition current = enumerator.Current; if (!current.HasBody) { continue; } ILProcessor iLProcessor = current.Body.GetILProcessor(); List list = ((IEnumerable)current.Body.Instructions).ToList(); foreach (Instruction item in list) { if (IsCall(item)) { object operand = item.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && ((MemberReference)val).Name == "DropAllHeldItems" && val.Parameters.Count == 2) { item.OpCode = OpCodes.Call; item.Operand = ((MemberReference)type).Module.ImportReference((MethodReference)(object)helperMethod); result = true; Console.WriteLine("[SurfacedPatcher] Redirect BellCrab DropAllHeldItems -> stub in " + ((MemberReference)type).FullName + "::" + ((MemberReference)current).Name); } } } } } finally { ((IDisposable)enumerator).Dispose(); } return result; } private static MethodDefinition EnsureBellCrabStub(ModuleDefinition module) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) TypeDefinition val = ((IEnumerable)module.Types).FirstOrDefault((Func)((TypeDefinition t) => ((TypeReference)t).Namespace == "SurfacedCompat" && ((MemberReference)t).Name == "GeneratedHelpers")); if (val == null) { val = new TypeDefinition("SurfacedCompat", "GeneratedHelpers", (TypeAttributes)1048960, module.TypeSystem.Object); module.Types.Add(val); } MethodDefinition val2 = ((IEnumerable)val.Methods).FirstOrDefault((Func)((MethodDefinition m) => ((MemberReference)m).Name == "BellCrabDropStub" && ((MethodReference)m).Parameters.Count == 3)); if (val2 != null) { return val2; } MethodDefinition val3 = new MethodDefinition("BellCrabDropStub", (MethodAttributes)150, module.TypeSystem.Void); ((MethodReference)val3).Parameters.Add(new ParameterDefinition("playerController", (ParameterAttributes)0, module.TypeSystem.Object)); ((MethodReference)val3).Parameters.Add(new ParameterDefinition("itemsFall", (ParameterAttributes)0, module.TypeSystem.Boolean)); ((MethodReference)val3).Parameters.Add(new ParameterDefinition("disconnecting", (ParameterAttributes)0, module.TypeSystem.Boolean)); ILProcessor iLProcessor = val3.Body.GetILProcessor(); iLProcessor.Append(Instruction.Create(OpCodes.Ret)); val.Methods.Add(val3); return val3; } private static bool IsCall(Instruction instr) { //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_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) return instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt; } }