using System; using System.Collections.Generic; using System.ComponentModel; 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 System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using HarmonyLib; using Mono.Cecil; using MonoMod.Utils; using SemanticVersioning; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("BepInEx.Unity.Mono.Preloader")] [assembly: InternalsVisibleTo("BepInEx.NET.Framework.Launcher")] [assembly: InternalsVisibleTo("BepInEx.NET.CoreCLR")] [assembly: InternalsVisibleTo("BepInEx.Unity.IL2CPP")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("BepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2022 BepInEx Team")] [assembly: AssemblyDescription("Core classes and utilities for BepInEx Preloader")] [assembly: AssemblyFileVersion("6.0.0.0")] [assembly: AssemblyInformationalVersion("6.0.0-be.674+82077ec7c91c97f0e5f8ada5d178fd7ece6c0099")] [assembly: AssemblyProduct("BepInEx.Preloader.Core")] [assembly: AssemblyTitle("BepInEx.Preloader.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/BepInEx/BepInEx")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("6.0.0.0")] [module: UnverifiableCode] namespace BepInEx.Preloader.RuntimeFixes { public static class ConsoleSetOutFix { private static LoggedTextWriter loggedTextWriter; internal static ManualLogSource ConsoleLogSource = Logger.CreateLogSource("Console"); public static void Apply() { loggedTextWriter = new LoggedTextWriter { Parent = Console.Out }; Console.SetOut(loggedTextWriter); Harmony.CreateAndPatchAll(typeof(ConsoleSetOutFix), (string)null); } [HarmonyPatch(typeof(Console), "SetOut")] [HarmonyPrefix] private static bool OnSetOut(TextWriter newOut) { loggedTextWriter.Parent = newOut; return false; } } internal class LoggedTextWriter : TextWriter { public override Encoding Encoding { get; } = Encoding.UTF8; public TextWriter Parent { get; set; } public override void Flush() { Parent.Flush(); } public override void Write(string value) { ConsoleSetOutFix.ConsoleLogSource.Log((LogLevel)16, (object)value); Parent.Write(value); } public override void WriteLine(string value) { ConsoleSetOutFix.ConsoleLogSource.Log((LogLevel)16, (object)value); Parent.WriteLine(value); } } public static class HarmonyBackendFix { private enum MonoModBackend { [Description("Auto")] auto, [Description("DynamicMethod")] dynamicmethod, [Description("MethodBuilder")] methodbuilder, [Description("Cecil")] cecil } private static readonly ConfigEntry ConfigHarmonyBackend = ConfigFile.CoreConfig.Bind("Preloader", "HarmonyBackend", MonoModBackend.auto, "Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.\nThis setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting."); public static void Initialize() { switch (ConfigHarmonyBackend.Value) { case MonoModBackend.dynamicmethod: case MonoModBackend.methodbuilder: case MonoModBackend.cecil: Environment.SetEnvironmentVariable("MONOMOD_DMD_TYPE", ConfigHarmonyBackend.Value.ToString()); break; default: throw new ArgumentOutOfRangeException("ConfigHarmonyBackend", ConfigHarmonyBackend.Value, "Unknown backend"); case MonoModBackend.auto: break; } } } } namespace BepInEx.Preloader.Core { public class AssemblyBuildInfo { public enum FrameworkType { Unknown, NetFramework, NetStandard, NetCore } public Version NetFrameworkVersion { get; private set; } public bool IsAnyCpu { get; set; } public bool Is64Bit { get; set; } public FrameworkType AssemblyFrameworkType { get; set; } private void SetNet4Version(AssemblyDefinition assemblyDefinition) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) NetFrameworkVersion = new Version(0, 0); AssemblyFrameworkType = FrameworkType.Unknown; CustomAttribute val = ((IEnumerable)assemblyDefinition.CustomAttributes).FirstOrDefault((Func)((CustomAttribute x) => ((MemberReference)x.AttributeType).FullName == "System.Runtime.Versioning.TargetFrameworkAttribute")); if (val == null || val.ConstructorArguments.Count < 1) { return; } CustomAttributeArgument val2 = val.ConstructorArguments[0]; if (((MemberReference)((CustomAttributeArgument)(ref val2)).Type).Name != "String") { return; } val2 = val.ConstructorArguments[0]; string[] array = ((string)((CustomAttributeArgument)(ref val2)).Value).Split(new char[1] { ',' }); foreach (string text in array) { if (text.StartsWith(".NET")) { AssemblyFrameworkType = text switch { ".NETFramework" => FrameworkType.NetFramework, ".NETCoreApp" => FrameworkType.NetCore, ".NETStandard" => FrameworkType.NetStandard, _ => FrameworkType.Unknown, }; } else if (text.StartsWith("Version=v")) { try { NetFrameworkVersion = new Version(text.Substring("Version=v".Length)); } catch { } } } } public static AssemblyBuildInfo DetermineInfo(AssemblyDefinition assemblyDefinition) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) AssemblyBuildInfo assemblyBuildInfo = new AssemblyBuildInfo(); TargetRuntime runtime = assemblyDefinition.MainModule.Runtime; if ((int)runtime == 0) { assemblyBuildInfo.NetFrameworkVersion = new Version(1, 0); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else if ((int)runtime == 1) { assemblyBuildInfo.NetFrameworkVersion = new Version(1, 1); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else if ((int)runtime == 2) { assemblyBuildInfo.NetFrameworkVersion = new Version(3, 5); assemblyBuildInfo.AssemblyFrameworkType = FrameworkType.NetFramework; } else { assemblyBuildInfo.SetNet4Version(assemblyDefinition); } TargetArchitecture architecture = assemblyDefinition.MainModule.Architecture; ModuleAttributes attributes = assemblyDefinition.MainModule.Attributes; if ((int)architecture == 34404) { assemblyBuildInfo.Is64Bit = true; assemblyBuildInfo.IsAnyCpu = false; } else if ((int)architecture == 332 && HasFlag(attributes, (ModuleAttributes)131074)) { assemblyBuildInfo.Is64Bit = false; assemblyBuildInfo.IsAnyCpu = true; } else if ((int)architecture == 332 && HasFlag(attributes, (ModuleAttributes)2)) { assemblyBuildInfo.Is64Bit = false; assemblyBuildInfo.IsAnyCpu = false; } else { if ((int)architecture != 332) { throw new Exception("Unable to determine assembly architecture"); } assemblyBuildInfo.Is64Bit = true; assemblyBuildInfo.IsAnyCpu = true; } return assemblyBuildInfo; } private static bool HasFlag(ModuleAttributes value, ModuleAttributes flag) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (ModuleAttributes)(value & flag) == flag; } public override string ToString() { string arg = AssemblyFrameworkType switch { FrameworkType.NetFramework => "Framework", FrameworkType.NetStandard => "Standard", FrameworkType.NetCore => "Core", FrameworkType.Unknown => "Unknown", _ => throw new ArgumentOutOfRangeException(), }; if (IsAnyCpu) { return string.Format(".NET {0} {1}, AnyCPU ({2}-bit preferred)", arg, NetFrameworkVersion, Is64Bit ? "64" : "32"); } return string.Format(".NET {0} {1}, {2}", arg, NetFrameworkVersion, Is64Bit ? "x64" : "x86"); } } public static class EnvVars { public static string DOORSTOP_INVOKE_DLL_PATH { get; private set; } public static string DOORSTOP_MANAGED_FOLDER_DIR { get; private set; } public static string DOORSTOP_PROCESS_PATH { get; private set; } public static string[] DOORSTOP_DLL_SEARCH_DIRS { get; private set; } public static string DOORSTOP_MONO_LIB_PATH { get; private set; } internal static void LoadVars() { DOORSTOP_INVOKE_DLL_PATH = Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH"); DOORSTOP_MANAGED_FOLDER_DIR = Environment.GetEnvironmentVariable("DOORSTOP_MANAGED_FOLDER_DIR"); DOORSTOP_PROCESS_PATH = Environment.GetEnvironmentVariable("DOORSTOP_PROCESS_PATH"); DOORSTOP_MONO_LIB_PATH = Environment.GetEnvironmentVariable("DOORSTOP_MONO_LIB_PATH"); DOORSTOP_DLL_SEARCH_DIRS = Environment.GetEnvironmentVariable("DOORSTOP_DLL_SEARCH_DIRS")?.Split(new char[1] { Path.PathSeparator }) ?? new string[0]; } } public static class PreloaderLogger { public static ManualLogSource Log { get; } = Logger.CreateLogSource("Preloader"); } internal static class PlatformUtils { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.LPStr)] private delegate string GetWineVersionDelegate(); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] public struct WindowsOSVersionInfoExW { public uint dwOSVersionInfoSize; public uint dwMajorVersion; public uint dwMinorVersion; public uint dwBuildNumber; public uint dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; public WindowsOSVersionInfoExW() { dwOSVersionInfoSize = (uint)Marshal.SizeOf(typeof(WindowsOSVersionInfoExW)); dwMajorVersion = 0u; dwMinorVersion = 0u; dwBuildNumber = 0u; dwPlatformId = 0u; szCSDVersion = null; wServicePackMajor = 0; wServicePackMinor = 0; wSuiteMask = 0; wProductType = 0; wReserved = 0; } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct utsname_osx { private const int osx_utslen = 256; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string sysname; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string nodename; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string release; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string version; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string machine; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct utsname_linux { private const int linux_utslen = 65; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string sysname; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string nodename; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string release; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string version; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string machine; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)] public string domainname; } public static readonly bool ProcessIs64Bit = IntPtr.Size >= 8; public static Version WindowsVersion { get; set; } public static string WineVersion { get; set; } public static string LinuxArchitecture { get; set; } public static string LinuxKernelVersion { get; set; } [DllImport("libc.so.6", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")] private static extern IntPtr uname_linux(ref utsname_linux utsname); [DllImport("/usr/lib/libSystem.dylib", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "uname")] private static extern IntPtr uname_osx(ref utsname_osx utsname); [DllImport("ntdll.dll", SetLastError = true)] private static extern bool RtlGetVersion(ref WindowsOSVersionInfoExW versionInfo); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr LoadLibrary(string libraryName); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); private static bool Is(this Platform current, Platform expected) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (Platform)(current & expected) == expected; } public static void SetPlatform() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) Platform val = (Platform)17; PropertyInfo property = typeof(Environment).GetProperty("Platform", BindingFlags.Static | BindingFlags.NonPublic); string text = ((!(property != null)) ? Environment.OSVersion.Platform.ToString() : property.GetValue(null, new object[0]).ToString()); text = text.ToLowerInvariant(); if (text.Contains("win")) { val = (Platform)37; } else if (text.Contains("mac") || text.Contains("osx")) { val = (Platform)73; } else if (text.Contains("lin") || text.Contains("unix")) { val = (Platform)137; } if (val.Is((Platform)137) && Directory.Exists("/data") && File.Exists("/system/build.prop")) { val = (Platform)393; } else if (val.Is((Platform)8) && Directory.Exists("/System/Library/AccessibilityBundles")) { val = (Platform)585; } if (val.Is((Platform)37)) { WindowsOSVersionInfoExW versionInfo = new WindowsOSVersionInfoExW(); RtlGetVersion(ref versionInfo); WindowsVersion = new Version((int)versionInfo.dwMajorVersion, (int)versionInfo.dwMinorVersion, 0, (int)versionInfo.dwBuildNumber); IntPtr intPtr = LoadLibrary("ntdll.dll"); if (intPtr != IntPtr.Zero) { IntPtr procAddress = GetProcAddress(intPtr, "wine_get_version"); if (procAddress != IntPtr.Zero) { val = (Platform)(val | 0x20000); WineVersion = DynDll.AsDelegate(procAddress)(); } } } MethodInfo methodInfo = typeof(Environment).GetProperty("Is64BitOperatingSystem")?.GetGetMethod(); val = (Platform)((!(methodInfo != null)) ? (val | ((IntPtr.Size >= 8) ? 2 : 0)) : (val | (((bool)methodInfo.Invoke(null, new object[0])) ? 2 : 0))); if ((val.Is((Platform)73) || val.Is((Platform)137)) && Type.GetType("Mono.Runtime") != null) { IntPtr intPtr2; string machine; if (val.Is((Platform)73)) { utsname_osx utsname = default(utsname_osx); intPtr2 = uname_osx(ref utsname); machine = utsname.machine; } else { utsname_linux utsname2 = default(utsname_linux); intPtr2 = uname_linux(ref utsname2); machine = utsname2.machine; LinuxArchitecture = utsname2.machine; LinuxKernelVersion = utsname2.version; } if (intPtr2 == IntPtr.Zero && (machine.StartsWith("aarch") || machine.StartsWith("arm"))) { val = (Platform)(val | 0x10000); } } else { typeof(object).Module.GetPEKind(out var _, out var machine2); if (machine2 == ImageFileMachine.ARM) { val = (Platform)(val | 0x10000); } } PlatformHelper.Current = val; } } } namespace BepInEx.Preloader.Core.Patching { public class AssemblyPatcher : IDisposable { private static readonly string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name; private Func assemblyLoader; private static readonly ConfigEntry ConfigDumpAssemblies = ConfigFile.CoreConfig.Bind("Preloader", "DumpAssemblies", false, "If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.\nThis can be used by developers to inspect and debug preloader patchers."); private static readonly ConfigEntry ConfigLoadDumpedAssemblies = ConfigFile.CoreConfig.Bind("Preloader", "LoadDumpedAssemblies", false, "If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.\nThis can be used to be able to load patched assemblies into debuggers like dnSpy.\nIf set to true, will override DumpAssemblies."); private static readonly ConfigEntry ConfigBreakBeforeLoadAssemblies = ConfigFile.CoreConfig.Bind("Preloader", "BreakBeforeLoadAssemblies", false, "If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.\nThis can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded."); public PatcherContext PatcherContext { get; } = new PatcherContext { DumpedAssembliesPath = Utility.CombinePaths(new string[3] { Paths.BepInExRootPath, "DumpedAssemblies", Paths.ProcessName }) }; private IEnumerable PatcherPluginsSafe => PatcherContext.PatcherPlugins.ToList(); private ManualLogSource Logger { get; } = Logger.CreateLogSource("AssemblyPatcher"); private static Regex allowedGuidRegex { get; } = new Regex("^[a-zA-Z0-9\\._\\-]+$"); public AssemblyPatcher(Func assemblyLoader) { this.assemblyLoader = assemblyLoader; } public void Dispose() { foreach (KeyValuePair availableAssembly in PatcherContext.AvailableAssemblies) { availableAssembly.Value.Dispose(); } PatcherContext.AvailableAssemblies.Clear(); PatcherContext.AvailableAssembliesPaths.Clear(); PatcherContext.PatcherPlugins.Clear(); } private PatcherPluginMetadata ToPatcherPlugin(TypeDefinition type, string assemblyPath) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (type.IsInterface || (type.IsAbstract && !type.IsSealed)) { return null; } try { if (!Utility.IsSubtypeOf(type, typeof(BasePatcher))) { return null; } } catch (AssemblyResolutionException) { return null; } PatcherPluginInfoAttribute patcherPluginInfoAttribute = PatcherPluginInfoAttribute.FromCecilType(type); bool flag = default(bool); if (patcherPluginInfoAttribute == null) { ManualLogSource logger = Logger; LogLevel val2 = (LogLevel)4; LogLevel val3 = val2; BepInExLogInterpolatedStringHandler val4 = new BepInExLogInterpolatedStringHandler(59, 1, val2, ref flag); if (flag) { val4.AppendLiteral("Skipping over type ["); val4.AppendFormatted(((MemberReference)type).FullName); val4.AppendLiteral("] as no metadata attribute is specified"); } logger.Log(val3, val4); return null; } if (string.IsNullOrEmpty(patcherPluginInfoAttribute.GUID) || !allowedGuidRegex.IsMatch(patcherPluginInfoAttribute.GUID)) { ManualLogSource logger2 = Logger; LogLevel val3 = (LogLevel)4; LogLevel val2 = val3; BepInExLogInterpolatedStringHandler val4 = new BepInExLogInterpolatedStringHandler(60, 2, val3, ref flag); if (flag) { val4.AppendLiteral("Skipping type ["); val4.AppendFormatted(((MemberReference)type).FullName); val4.AppendLiteral("] because its GUID ["); val4.AppendFormatted(patcherPluginInfoAttribute.GUID); val4.AppendLiteral("] is of an illegal format"); } logger2.Log(val2, val4); return null; } if (patcherPluginInfoAttribute.Version == (Version)null) { ManualLogSource logger3 = Logger; LogLevel val2 = (LogLevel)4; LogLevel val3 = val2; BepInExLogInterpolatedStringHandler val4 = new BepInExLogInterpolatedStringHandler(47, 1, val2, ref flag); if (flag) { val4.AppendLiteral("Skipping type ["); val4.AppendFormatted(((MemberReference)type).FullName); val4.AppendLiteral("] because its version is invalid"); } logger3.Log(val3, val4); return null; } if (patcherPluginInfoAttribute.Name == null) { ManualLogSource logger4 = Logger; LogLevel val3 = (LogLevel)4; LogLevel val2 = val3; BepInExLogInterpolatedStringHandler val4 = new BepInExLogInterpolatedStringHandler(41, 1, val3, ref flag); if (flag) { val4.AppendLiteral("Skipping type ["); val4.AppendFormatted(((MemberReference)type).FullName); val4.AppendLiteral("] because its name is null"); } logger4.Log(val2, val4); return null; } return new PatcherPluginMetadata { TypeName = ((MemberReference)type).FullName }; } private bool HasPatcherPlugins(AssemblyDefinition ass) { if (((IEnumerable)ass.MainModule.AssemblyReferences).All((AssemblyNameReference r) => r.Name != CurrentAssemblyName) && ((AssemblyNameReference)ass.Name).Name != CurrentAssemblyName) { return false; } if (ass.MainModule.GetTypeReferences().All((TypeReference r) => ((MemberReference)r).FullName != typeof(BasePatcher).FullName)) { return false; } return true; } public void AddPatchersFromDirectory(string directory) { //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) if (!Directory.Exists(directory)) { return; } List sortedPatchers = new List(); bool flag = default(bool); foreach (KeyValuePair> item in TypeLoader.FindPluginTypes(directory, (Func)ToPatcherPlugin, (Func)HasPatcherPlugins, (string)null)) { string key = item.Key; List value = item.Value; if (value.Count == 0) { continue; } Assembly assembly = Assembly.LoadFrom(key); LogLevel val; LogLevel val2; BepInExLogInterpolatedStringHandler val3; foreach (PatcherPluginMetadata item2 in value) { try { Type? type = assembly.GetType(item2.TypeName); BasePatcher basePatcher = (BasePatcher)Activator.CreateInstance(type); basePatcher.Context = PatcherContext; PatcherContext.PatcherPlugins.Add(basePatcher); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { TargetAssemblyAttribute[] attributes = MetadataHelper.GetAttributes((MemberInfo)methodInfo); TargetTypeAttribute[] attributes2 = MetadataHelper.GetAttributes((MemberInfo)methodInfo); if (attributes.Length == 0 && attributes2.Length == 0) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length < 1 || parameters.Length > 2 || (!(parameters[0].ParameterType == typeof(AssemblyDefinition)) && (!(parameters[0].ParameterType == typeof(AssemblyDefinition).MakeByRefType()) || attributes2.Length != 0) && (!(parameters[0].ParameterType == typeof(TypeDefinition)) || attributes.Length != 0)) || (parameters.Length == 2 && parameters[1].ParameterType != typeof(string)) || (methodInfo.ReturnType != typeof(void) && methodInfo.ReturnType != typeof(bool))) { ManualLogSource logger = Logger; val = (LogLevel)4; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(54, 1, val, ref flag); if (flag) { val3.AppendLiteral("Skipping method ["); val3.AppendFormatted(GeneralExtensions.FullDescription((MethodBase)methodInfo)); val3.AppendLiteral("] as it is not a valid patcher method"); } logger.Log(val2, val3); } else { TargetAssemblyAttribute[] array = attributes; foreach (TargetAssemblyAttribute targetAssembly in array) { AddDefinition(new PatchDefinition(targetAssembly, basePatcher, methodInfo)); } TargetTypeAttribute[] array2 = attributes2; foreach (TargetTypeAttribute targetType in array2) { AddDefinition(new PatchDefinition(targetType, basePatcher, methodInfo)); } } } } catch (Exception ex) { ManualLogSource logger2 = Logger; val2 = (LogLevel)2; val = val2; val3 = new BepInExLogInterpolatedStringHandler(38, 2, val2, ref flag); if (flag) { val3.AppendLiteral("Failed to load patchers from type ["); val3.AppendFormatted(item2.TypeName); val3.AppendLiteral("]: "); val3.AppendFormatted((ex is ReflectionTypeLoadException ex2) ? TypeLoader.TypeLoadExceptionToString(ex2) : ex.ToString()); } logger2.Log(val, val3); } } AssemblyName name = assembly.GetName(); ManualLogSource logger3 = Logger; val = (LogLevel)(value.Any() ? 16 : 32); val2 = val; val3 = new BepInExLogInterpolatedStringHandler(29, 4, val, ref flag); if (flag) { val3.AppendLiteral("Loaded "); val3.AppendFormatted(value.Count); val3.AppendLiteral(" patcher type"); val3.AppendFormatted((value.Count == 1) ? "" : "s"); val3.AppendLiteral(" from ["); val3.AppendFormatted(name.Name); val3.AppendLiteral(" "); val3.AppendFormatted(name.Version); val3.AppendLiteral("]"); } logger3.Log(val2, val3); } PatcherContext.PatchDefinitions.AddRange(sortedPatchers); void AddDefinition(PatchDefinition definition) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger4 = Logger; LogLevel val4 = (LogLevel)32; LogLevel val5 = val4; bool flag2 = default(bool); BepInExLogInterpolatedStringHandler val6 = new BepInExLogInterpolatedStringHandler(19, 1, val4, ref flag2); if (flag2) { val6.AppendLiteral("Discovered patch ["); val6.AppendFormatted(definition.FullName); val6.AppendLiteral("]"); } logger4.Log(val5, val6); sortedPatchers.Add(definition); } } public void LoadAssemblyDirectories(params string[] directories) { LoadAssemblyDirectories(directories, new string[1] { "dll" }); } public void LoadAssemblyDirectories(IEnumerable directories, IEnumerable assemblyExtensions) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown bool flag = default(bool); foreach (string item in assemblyExtensions.SelectMany((string ext) => Utility.GetUniqueFilesInDirectories(directories, "*." + ext))) { if (!TryLoadAssembly(item, out var assembly)) { continue; } if (((AssemblyNameReference)assembly.Name).Name == "System" || ((AssemblyNameReference)assembly.Name).Name == "mscorlib") { assembly.Dispose(); continue; } string fileName = Path.GetFileName(item); PatcherContext.AvailableAssemblies.Add(fileName, assembly); PatcherContext.AvailableAssembliesPaths.Add(fileName, item); ManualLogSource logger = Logger; BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Assembly loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Path.GetFileName(item)); } logger.LogDebug(val); } } public static bool TryLoadAssembly(string path, out AssemblyDefinition assembly) { try { assembly = AssemblyDefinition.ReadAssembly(path, TypeLoader.ReaderParameters); return true; } catch (BadImageFormatException) { assembly = null; return false; } } public void PatchAndLoad() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06f7: Unknown result type (might be due to invalid IL or missing references) //IL_06fb: Unknown result type (might be due to invalid IL or missing references) //IL_0702: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_073a: 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_00ea: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Expected O, but got Unknown //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Expected O, but got Unknown //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Expected O, but got Unknown //IL_0698: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(PatcherContext.AvailableAssemblies, StringComparer.InvariantCultureIgnoreCase); bool flag = default(bool); LogLevel val2; LogLevel val; BepInExLogInterpolatedStringHandler val3; foreach (BasePatcher item in PatcherPluginsSafe) { try { item.Initialize(); } catch (Exception ex) { ManualLogSource logger = Logger; val = (LogLevel)2; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(31, 2, val, ref flag); if (flag) { val3.AppendLiteral("Failed to run initializer of "); val3.AppendFormatted(item.Info.GUID); val3.AppendLiteral(": "); val3.AppendFormatted(ex); } logger.Log(val2, val3); } } HashSet patchedAssemblies = new HashSet(StringComparer.InvariantCultureIgnoreCase); Dictionary dictionary2 = new Dictionary(); HashSet invalidAssemblies = new HashSet(StringComparer.InvariantCultureIgnoreCase); ManualLogSource logger2 = Logger; val2 = (LogLevel)8; val = val2; val3 = new BepInExLogInterpolatedStringHandler(20, 1, val2, ref flag); if (flag) { val3.AppendLiteral("Executing "); val3.AppendFormatted(PatcherContext.PatchDefinitions.Count); val3.AppendLiteral(" patch(es)"); } logger2.Log(val, val3); AssemblyName assemblyName = default(AssemblyName); foreach (PatchDefinition item2 in PatcherContext.PatchDefinitions.ToList()) { PatchDefinition patchDefinition = item2; string text = patchDefinition.TargetAssembly?.TargetAssembly ?? patchDefinition.TargetType.TargetAssembly; bool isAssemblyPatch = patchDefinition.TargetAssembly != null; if (text == "_all") { foreach (KeyValuePair item3 in PatcherContext.AvailableAssemblies.ToList()) { if (!invalidAssemblies.Contains(item3.Key)) { RunPatcher(item3.Value, item3.Key); } } } else { if (!PatcherContext.AvailableAssemblies.TryGetValue(text, out var value) || invalidAssemblies.Contains(text)) { continue; } RunPatcher(value, text); } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { string key = (Utility.TryParseAssemblyName(assembly2.FullName, ref assemblyName) ? assemblyName.Name : assembly2.FullName); if (!dictionary2.ContainsKey(key)) { dictionary2[key] = patchDefinition.MethodInfo.DeclaringType.ToString(); } } bool RunPatcher(AssemblyDefinition assembly, string targetDll) { //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown try { object[] array = new object[patchDefinition.MethodInfo.GetParameters().Length]; if (!isAssemblyPatch) { TypeDefinition val4 = ((IEnumerable)assembly.MainModule.Types).FirstOrDefault((Func)((TypeDefinition x) => ((MemberReference)x).FullName == patchDefinition.TargetType.TargetType)); if (val4 == null) { ManualLogSource logger7 = Logger; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(52, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Unable to find type ["); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(patchDefinition.TargetType.TargetType); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] defined in "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(patchDefinition.MethodInfo.Name); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(". Skipping patcher"); } logger7.LogWarning(val5); return false; } array[0] = val4; } else { array[0] = assembly; } if (array.Length > 1) { array[1] = targetDll; } object obj = patchDefinition.MethodInfo.Invoke(patchDefinition.Instance, array); if (patchDefinition.MethodInfo.ReturnType == typeof(void) || (patchDefinition.MethodInfo.ReturnType == typeof(bool) && (bool)obj)) { if (isAssemblyPatch) { assembly = (AssemblyDefinition)array[0]; PatcherContext.AvailableAssemblies[targetDll] = assembly; } patchedAssemblies.Add(targetDll); } return true; } catch (Exception ex3) { ManualLogSource logger8 = Logger; LogLevel val6 = (LogLevel)2; LogLevel val7 = val6; bool flag3 = default(bool); BepInExLogInterpolatedStringHandler val8 = new BepInExLogInterpolatedStringHandler(77, 3, val6, ref flag3); if (flag3) { val8.AppendLiteral("Failed to run ["); val8.AppendFormatted(patchDefinition.FullName); val8.AppendLiteral("] when patching ["); val8.AppendFormatted(((AssemblyNameReference)assembly.Name).Name); val8.AppendLiteral("]. This assembly will not be patched. Error: "); val8.AppendFormatted(ex3); } logger8.Log(val7, val8); patchedAssemblies.Remove(targetDll); invalidAssemblies.Add(targetDll); return false; } } } HashSet patchedAssemblyNames = new HashSet(from kv in dictionary where patchedAssemblies.Contains(kv.Key) select ((AssemblyNameReference)kv.Value.Name).Name, StringComparer.InvariantCultureIgnoreCase); List> list = dictionary2.Where((KeyValuePair kv) => patchedAssemblyNames.Contains(kv.Key)).ToList(); if (list.Count != 0) { Logger.Log((LogLevel)4, (object)new StringBuilder().AppendLine("The following assemblies have been loaded too early and will not be patched by preloader:").AppendLine(string.Join(Environment.NewLine, list.Select((KeyValuePair kv) => "* [" + kv.Key + "] (first loaded by [" + kv.Value + "])").ToArray())).AppendLine("Expect unexpected behavior and issues with plugins and patchers not being loaded.") .ToString()); } Dictionary dictionary3 = new Dictionary(); if (ConfigDumpAssemblies.Value || ConfigLoadDumpedAssemblies.Value) { if (!Directory.Exists(PatcherContext.DumpedAssembliesPath)) { Directory.CreateDirectory(PatcherContext.DumpedAssembliesPath); } FileStream fileStream = default(FileStream); foreach (KeyValuePair item4 in dictionary) { string key2 = item4.Key; string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(key2); string extension = Path.GetExtension(key2); AssemblyDefinition value2 = item4.Value; if (!patchedAssemblies.Contains(key2)) { continue; } int num = 0; string text3; while (true) { string text2 = ((num > 0) ? $"_{num}" : ""); text3 = Path.Combine(PatcherContext.DumpedAssembliesPath, fileNameWithoutExtension + text2 + extension); if (Utility.TryOpenFileStream(text3, FileMode.Create, ref fileStream, FileAccess.ReadWrite, FileShare.Read)) { break; } num++; } value2.Write((Stream)fileStream); fileStream.Dispose(); dictionary3[key2] = text3; } } if (ConfigBreakBeforeLoadAssemblies.Value) { ManualLogSource logger3 = Logger; val = (LogLevel)16; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(48, 1, val, ref flag); if (flag) { val3.AppendLiteral("BepInEx is about load the following assemblies:\n"); val3.AppendFormatted(string.Join("\n", patchedAssemblies.ToArray())); } logger3.Log(val2, val3); ManualLogSource logger4 = Logger; val2 = (LogLevel)16; val = val2; val3 = new BepInExLogInterpolatedStringHandler(32, 1, val2, ref flag); if (flag) { val3.AppendLiteral("The assemblies were dumped into "); val3.AppendFormatted(PatcherContext.DumpedAssembliesPath); } logger4.Log(val, val3); Logger.Log((LogLevel)16, (object)"Load any assemblies into the debugger, set breakpoints and continue execution."); Debugger.Break(); } foreach (KeyValuePair item5 in dictionary) { string key3 = item5.Key; AssemblyDefinition value3 = item5.Value; if (patchedAssemblies.Contains(key3)) { Assembly value5; if (ConfigLoadDumpedAssemblies.Value && dictionary3.TryGetValue(key3, out var value4)) { value5 = Assembly.LoadFrom(value4); } else { using MemoryStream memoryStream = new MemoryStream(); value3.Write((Stream)memoryStream); value5 = assemblyLoader(memoryStream.ToArray(), PatcherContext.AvailableAssembliesPaths[key3]); } PatcherContext.LoadedAssemblies.Add(key3, value5); ManualLogSource logger5 = Logger; val = (LogLevel)32; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(21, 1, val, ref flag); if (flag) { val3.AppendLiteral("Loaded '"); val3.AppendFormatted(value3.FullName); val3.AppendLiteral("' into memory"); } logger5.Log(val2, val3); } value3.Dispose(); } foreach (BasePatcher item6 in PatcherPluginsSafe) { try { item6.Finalizer(); } catch (Exception ex2) { ManualLogSource logger6 = Logger; val2 = (LogLevel)2; val = val2; val3 = new BepInExLogInterpolatedStringHandler(29, 2, val2, ref flag); if (flag) { val3.AppendLiteral("Failed to run finalizer of "); val3.AppendFormatted(item6.Info.GUID); val3.AppendLiteral(": "); val3.AppendFormatted(ex2); } logger6.Log(val, val3); } } } } [AttributeUsage(AttributeTargets.Class)] public class PatcherPluginInfoAttribute : Attribute { public string GUID { get; protected set; } public string Name { get; protected set; } public Version Version { get; protected set; } public PatcherPluginInfoAttribute(string GUID, string Name, string Version) { this.GUID = GUID; this.Name = Name; this.Version = TryParseLongVersion(Version); } private static Version TryParseLongVersion(string version) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Version result = default(Version); if (Version.TryParse(version, ref result)) { return result; } try { Version version2 = new Version(version); return new Version(version2.Major, version2.Minor, (version2.Build != -1) ? version2.Build : 0, (string)null, (string)null); } catch { } return null; } internal static PatcherPluginInfoAttribute FromCecilType(TypeDefinition td) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) CustomAttribute val = MetadataHelper.GetCustomAttributes(td, false).FirstOrDefault(); if (val == null) { return null; } CustomAttributeArgument val2 = val.ConstructorArguments[0]; string gUID = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[1]; string name = (string)((CustomAttributeArgument)(ref val2)).Value; val2 = val.ConstructorArguments[2]; return new PatcherPluginInfoAttribute(gUID, name, (string)((CustomAttributeArgument)(ref val2)).Value); } internal static PatcherPluginInfoAttribute FromType(Type type) { object[] customAttributes = type.GetCustomAttributes(typeof(PatcherPluginInfoAttribute), inherit: false); if (customAttributes.Length == 0) { return null; } return (PatcherPluginInfoAttribute)customAttributes[0]; } } [AttributeUsage(AttributeTargets.Method)] public class TargetAssemblyAttribute : Attribute { public const string AllAssemblies = "_all"; public string TargetAssembly { get; } public TargetAssemblyAttribute(string targetAssembly) { TargetAssembly = targetAssembly; } } [AttributeUsage(AttributeTargets.Method)] public class TargetTypeAttribute : Attribute { public string TargetAssembly { get; } public string TargetType { get; } public TargetTypeAttribute(string targetAssembly, string targetType) { TargetAssembly = targetAssembly; TargetType = targetType; } } public abstract class BasePatcher { public ManualLogSource Log { get; } public ConfigFile Config { get; } public PatcherPluginInfoAttribute Info { get; } public PatcherContext Context { get; set; } protected BasePatcher() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown Info = PatcherPluginInfoAttribute.FromType(GetType()); Log = Logger.CreateLogSource(Info.Name); Config = new ConfigFile(Utility.CombinePaths(new string[2] { Paths.ConfigPath, Info.GUID + ".cfg" }), false, new BepInPlugin(Info.GUID, Info.Name, ((object)Info.Version).ToString())); } public virtual void Initialize() { } public virtual void Finalizer() { } } public class PatchDefinition { public TargetAssemblyAttribute TargetAssembly { get; } public TargetTypeAttribute TargetType { get; } public BasePatcher Instance { get; } public MethodInfo MethodInfo { get; } public string FullName { get; } public PatchDefinition(TargetAssemblyAttribute targetAssembly, BasePatcher instance, MethodInfo methodInfo) { TargetAssembly = targetAssembly; Instance = instance; MethodInfo = methodInfo; FullName = MethodInfo.DeclaringType.FullName + "/" + MethodInfo.Name + " -> " + TargetAssembly.TargetAssembly; } public PatchDefinition(TargetTypeAttribute targetType, BasePatcher instance, MethodInfo methodInfo) { TargetType = targetType; Instance = instance; MethodInfo = methodInfo; FullName = MethodInfo.DeclaringType.FullName + "/" + MethodInfo.Name + " -> " + TargetType.TargetAssembly + "/" + TargetType.TargetType; } } public class PatcherContext { public Dictionary AvailableAssemblies { get; } = new Dictionary(); public Dictionary AvailableAssembliesPaths { get; } = new Dictionary(); public Dictionary LoadedAssemblies { get; } = new Dictionary(); public List PatcherPlugins { get; } = new List(); public List PatchDefinitions { get; } = new List(); public string DumpedAssembliesPath { get; internal set; } } internal class PatcherPluginMetadata : ICacheable { public string TypeName { get; set; } = string.Empty; public void Save(BinaryWriter bw) { bw.Write(TypeName); } public void Load(BinaryReader br) { TypeName = br.ReadString(); } } } namespace BepInEx.Preloader.Core.Logging { public static class ChainloaderLogHelper { private static Dictionary MacOSVersions { get; } = new Dictionary { ["16.0.0"] = "10.12", ["16.5.0"] = "10.12.4", ["16.6.0"] = "10.12.6", ["17.5.0"] = "10.13.4", ["17.6.0"] = "10.13.5", ["17.7.0"] = "10.13.6", ["18.2.0"] = "10.14.1", ["19.2.0"] = "10.15.2", ["19.3.0"] = "10.15.3", ["19.5.0"] = "10.15.5.1", ["20.1.0"] = "11.0", ["20.2.0"] = "11.1", ["20.3.0"] = "11.2", ["20.4.0"] = "11.3", ["20.5.0"] = "11.4", ["21.0.1"] = "12.0", ["21.1.0"] = "12.0.1", ["21.2.0"] = "12.1" }; public static void PrintLogInfo(ManualLogSource log) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0093: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00dc: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) Version bepInExVersion = Paths.BepInExVersion; Version arg = new Version(bepInExVersion.Major, bepInExVersion.Minor, bepInExVersion.Patch, bepInExVersion.PreRelease, (string)null); string text = $"BepInEx {arg} - {Paths.ProcessName}"; log.Log((LogLevel)8, (object)text); if (ConsoleManager.ConsoleActive) { ConsoleManager.SetConsoleTitle(text); } bool flag = default(bool); LogLevel val2; BepInExLogInterpolatedStringHandler val3; if (!string.IsNullOrEmpty(bepInExVersion.Build)) { LogLevel val = (LogLevel)8; val2 = val; val3 = new BepInExLogInterpolatedStringHandler(18, 1, val, ref flag); if (flag) { val3.AppendLiteral("Built from commit "); val3.AppendFormatted(bepInExVersion.Build); } log.Log(val2, val3); } val2 = (LogLevel)16; LogLevel val4 = val2; val3 = new BepInExLogInterpolatedStringHandler(17, 1, val2, ref flag); if (flag) { val3.AppendLiteral("System platform: "); val3.AppendFormatted(GetPlatformString()); } Logger.Log(val4, val3); val2 = (LogLevel)16; LogLevel val5 = val2; val3 = new BepInExLogInterpolatedStringHandler(17, 1, val2, ref flag); if (flag) { val3.AppendLiteral("Process bitness: "); val3.AppendFormatted(PlatformUtils.ProcessIs64Bit ? "64-bit (x64)" : "32-bit (x86)"); } Logger.Log(val5, val3); } private static string GetPlatformString() { StringBuilder stringBuilder = new StringBuilder(); Version version = Environment.OSVersion.Version; if (PlatformHelper.Is((Platform)37)) { version = PlatformUtils.WindowsVersion; stringBuilder.Append("Windows "); if (version.Major >= 10 && version.Build >= 22000) { stringBuilder.Append("11"); } else if (version.Major >= 10) { stringBuilder.Append("10"); } else if (version.Major == 6 && version.Minor == 3) { stringBuilder.Append("8.1"); } else if (version.Major == 6 && version.Minor == 2) { stringBuilder.Append("8"); } else if (version.Major == 6 && version.Minor == 1) { stringBuilder.Append("7"); } else if (version.Major == 6 && version.Minor == 0) { stringBuilder.Append("Vista"); } else if (version.Major <= 5) { stringBuilder.Append("XP"); } if (PlatformHelper.Is((Platform)131072)) { stringBuilder.AppendFormat(" (Wine {0})", PlatformUtils.WineVersion); } } else if (PlatformHelper.Is((Platform)73)) { stringBuilder.Append("macOS "); string key = version.ToString(3); if (MacOSVersions.TryGetValue(key, out var value)) { stringBuilder.Append(value); } else { stringBuilder.AppendFormat("Unknown (kernel {0})", version); } } else if (PlatformHelper.Is((Platform)137)) { stringBuilder.Append("Linux"); if (PlatformUtils.LinuxKernelVersion != null) { stringBuilder.AppendFormat(" (kernel {0})", PlatformUtils.LinuxKernelVersion); } } stringBuilder.Append(PlatformHelper.Is((Platform)2) ? " 64-bit" : " 32-bit"); if (PlatformHelper.Is((Platform)393)) { stringBuilder.Append(" Android"); } if (PlatformHelper.Is((Platform)65536)) { stringBuilder.Append(" ARM"); if (PlatformHelper.Is((Platform)2)) { stringBuilder.Append("64"); } } return stringBuilder.ToString(); } public static void RewritePreloaderLogs() { if (PreloaderConsoleListener.LogEvents == null || PreloaderConsoleListener.LogEvents.Count == 0) { return; } ILogListener val = ((IEnumerable)Logger.Listeners).FirstOrDefault((Func)((ILogListener logger) => logger is ConsoleLogListener)); if (val != null) { Logger.Listeners.Remove(val); } foreach (LogEventArgs logEvent in PreloaderConsoleListener.LogEvents) { Logger.InternalLogEvent((object)PreloaderLogger.Log, logEvent); } if (val != null) { Logger.Listeners.Add(val); } } } public class PreloaderConsoleListener : ILogListener, IDisposable { private static readonly ConfigEntry ConfigConsoleDisplayedLevel = ConfigFile.CoreConfig.Bind("Logging.Console", "LogLevels", (LogLevel)31, "Which log levels to show in the console output."); public static List LogEvents { get; } = new List(); public LogLevel LogLevelFilter => ConfigConsoleDisplayedLevel.Value; public void LogEvent(object sender, LogEventArgs eventArgs) { LogEvents.Add(eventArgs); } public void Dispose() { } } }