Decompiled source of SurfacedCompatibilityFix v1.0.0

BepInEx/patchers/MariuszPatcher/MariuszPatcher.dll

Decompiled 3 days ago
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<string> TargetDLLs { get; } = Array.Empty<string>();


	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<MethodDefinition> enumerator = type.Methods.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				MethodDefinition current = enumerator.Current;
				if (!current.HasBody)
				{
					continue;
				}
				ILProcessor iLProcessor = current.Body.GetILProcessor();
				List<Instruction> list = ((IEnumerable<Instruction>)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<MethodDefinition> enumerator = type.Methods.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				MethodDefinition current = enumerator.Current;
				if (!current.HasBody)
				{
					continue;
				}
				ILProcessor iLProcessor = current.Body.GetILProcessor();
				List<Instruction> list = ((IEnumerable<Instruction>)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<MethodDefinition> enumerator = type.Methods.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				MethodDefinition current = enumerator.Current;
				if (!current.HasBody)
				{
					continue;
				}
				ILProcessor iLProcessor = current.Body.GetILProcessor();
				List<Instruction> list = ((IEnumerable<Instruction>)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<MethodDefinition> enumerator = type.Methods.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				MethodDefinition current = enumerator.Current;
				if (!current.HasBody)
				{
					continue;
				}
				ILProcessor iLProcessor = current.Body.GetILProcessor();
				List<Instruction> list = ((IEnumerable<Instruction>)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<TypeDefinition>)module.Types).FirstOrDefault((Func<TypeDefinition, bool>)((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<MethodDefinition>)val.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((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;
	}
}