Decompiled source of DiFFoZTweaks v1.7.2

BepInEx/plugins/DiFFoZTweaks/DiFFoZTweaks.dll

Decompiled a week ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using DiFFoZTweaks.Extensions;
using DiFFoZTweaks.MelaniesVoice;
using DiFFoZTweaks.Patcher;
using DiFFoZTweaks.Patcher.Configuration;
using DiFFoZTweaks.Utilities;
using GameNetcodeStuff;
using HarmonyLib;
using LethalPerformance.Audio;
using LethalPerformance.Patcher;
using Microsoft.CodeAnalysis;
using Netcode.Transports.Facepunch;
using SoftMasking;
using Steamworks;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
using com.github.zehsteam.MelaniesVoice.MonoBehaviours;
using com.github.zehsteam.MelaniesVoice.Objects;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DiFFoZTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.2.0")]
[assembly: AssemblyInformationalVersion("1.7.2+0b8a86f142277342d1cab6aaa46c38f8911c9c65")]
[assembly: AssemblyProduct("DiFFoZTweaks")]
[assembly: AssemblyTitle("DiFFoZTweaks")]
[assembly: AssemblyMetadata("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.2.0")]
[module: UnverifiableCode]
[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 Windows.Win32
{
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal static class PInvoke
	{
		[DllImport("KERNEL32.dll", ExactSpelling = true, SetLastError = true)]
		[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
		internal static extern BOOL CloseHandle(HANDLE hObject);

		internal unsafe static BOOL FlashWindowEx(in FLASHWINFO pfwi)
		{
			fixed (FLASHWINFO* pfwi2 = &pfwi)
			{
				return FlashWindowEx(pfwi2);
			}
		}

		[DllImport("USER32.dll", ExactSpelling = true)]
		[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
		internal unsafe static extern BOOL FlashWindowEx(FLASHWINFO* pfwi);

		[DllImport("USER32.dll", ExactSpelling = true)]
		[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
		internal static extern HWND GetActiveWindow();
	}
}
namespace Windows.Win32.UI.WindowsAndMessaging
{
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal struct FLASHWINFO
	{
		internal uint cbSize;

		internal HWND hwnd;

		internal FLASHWINFO_FLAGS dwFlags;

		internal uint uCount;

		internal uint dwTimeout;
	}
	[Flags]
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal enum FLASHWINFO_FLAGS : uint
	{
		FLASHW_ALL = 3u,
		FLASHW_CAPTION = 1u,
		FLASHW_STOP = 0u,
		FLASHW_TIMER = 4u,
		FLASHW_TIMERNOFG = 0xCu,
		FLASHW_TRAY = 2u
	}
}
namespace Windows.Win32.Foundation
{
	[DebuggerDisplay("{Value}")]
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal readonly struct BOOL : IEquatable<BOOL>
	{
		internal readonly int Value;

		internal BOOL(int value)
		{
			Value = value;
		}

		public static implicit operator int(BOOL value)
		{
			return value.Value;
		}

		public static explicit operator BOOL(int value)
		{
			return new BOOL(value);
		}

		public static bool operator ==(BOOL left, BOOL right)
		{
			return left.Value == right.Value;
		}

		public static bool operator !=(BOOL left, BOOL right)
		{
			return !(left == right);
		}

		public bool Equals(BOOL other)
		{
			return Value == other.Value;
		}

		public override bool Equals(object obj)
		{
			if (obj is BOOL other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		public override string ToString()
		{
			return $"0x{Value:x}";
		}

		internal BOOL(bool value)
		{
			Value = (value ? 1 : 0);
		}

		public static implicit operator bool(BOOL value)
		{
			return value.Value != 0;
		}

		public static implicit operator BOOL(bool value)
		{
			return new BOOL(value);
		}
	}
	[DebuggerDisplay("{Value}")]
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal readonly struct HANDLE : IEquatable<HANDLE>
	{
		internal unsafe readonly void* Value;

		internal static HANDLE Null => default(HANDLE);

		internal unsafe bool IsNull => Value == null;

		internal unsafe HANDLE(void* value)
		{
			Value = value;
		}

		internal unsafe HANDLE(IntPtr value)
			: this((void*)value)
		{
		}

		public unsafe static implicit operator void*(HANDLE value)
		{
			return value.Value;
		}

		public unsafe static explicit operator HANDLE(void* value)
		{
			return new HANDLE(value);
		}

		public unsafe static bool operator ==(HANDLE left, HANDLE right)
		{
			return left.Value == right.Value;
		}

		public static bool operator !=(HANDLE left, HANDLE right)
		{
			return !(left == right);
		}

		public unsafe bool Equals(HANDLE other)
		{
			return Value == other.Value;
		}

		public override bool Equals(object obj)
		{
			if (obj is HANDLE other)
			{
				return Equals(other);
			}
			return false;
		}

		public unsafe override int GetHashCode()
		{
			return (int)Value;
		}

		public unsafe override string ToString()
		{
			return $"0x{(nuint)Value:x}";
		}

		public unsafe static implicit operator IntPtr(HANDLE value)
		{
			return new IntPtr(value.Value);
		}

		public unsafe static explicit operator HANDLE(IntPtr value)
		{
			return new HANDLE(value.ToPointer());
		}

		public unsafe static explicit operator HANDLE(UIntPtr value)
		{
			return new HANDLE(value.ToPointer());
		}
	}
	[DebuggerDisplay("{Value}")]
	[GeneratedCode("Microsoft.Windows.CsWin32", "0.3.183+73e6125f79.RR")]
	internal readonly struct HWND : IEquatable<HWND>
	{
		internal unsafe readonly void* Value;

		internal static HWND Null => default(HWND);

		internal unsafe bool IsNull => Value == null;

		internal unsafe HWND(void* value)
		{
			Value = value;
		}

		internal unsafe HWND(IntPtr value)
			: this((void*)value)
		{
		}

		public unsafe static implicit operator void*(HWND value)
		{
			return value.Value;
		}

		public unsafe static explicit operator HWND(void* value)
		{
			return new HWND(value);
		}

		public unsafe static bool operator ==(HWND left, HWND right)
		{
			return left.Value == right.Value;
		}

		public static bool operator !=(HWND left, HWND right)
		{
			return !(left == right);
		}

		public unsafe bool Equals(HWND other)
		{
			return Value == other.Value;
		}

		public override bool Equals(object obj)
		{
			if (obj is HWND other)
			{
				return Equals(other);
			}
			return false;
		}

		public unsafe override int GetHashCode()
		{
			return (int)Value;
		}

		public unsafe override string ToString()
		{
			return $"0x{(nuint)Value:x}";
		}

		public unsafe static implicit operator IntPtr(HWND value)
		{
			return new IntPtr(value.Value);
		}

		public unsafe static explicit operator HWND(IntPtr value)
		{
			return new HWND(value.ToPointer());
		}

		public unsafe static explicit operator HWND(UIntPtr value)
		{
			return new HWND(value.ToPointer());
		}

		public unsafe static implicit operator HANDLE(HWND value)
		{
			return new HANDLE(value.Value);
		}
	}
}
namespace DiFFoZTweaks
{
	internal static class Dependencies
	{
		public const string MoreCompany = "me.swipez.melonloader.morecompany";

		public const string MelaniesVoice = "com.github.zehsteam.MelaniesVoice";

		public static bool TryGetMod(string id, out PluginInfo pluginInfo)
		{
			return Chainloader.PluginInfos.TryGetValue(id, out pluginInfo);
		}
	}
	[BepInPlugin("DiFFoZTweaks", "DiFFoZTweaks", "1.7.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DiFFoZTweaksPlugin : BaseUnityPlugin
	{
		private Harmony m_Harmony;

		public static DiFFoZTweaksPlugin Instance { get; private set; }

		public ConfigManager Config { get; private set; }

		public ManualLogSource Logger { get; private set; }

		private DiFFoZTweaksPlugin()
		{
		}

		internal void Awake()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Instance = this;
			Config = DiFFoZTweaksPatcher.Instance.Config;
			Logger = ((BaseUnityPlugin)this).Logger;
			m_Harmony = new Harmony("DiFFoZTweaks");
			m_Harmony.PatchAll(typeof(DiFFoZTweaksPlugin).Assembly);
			LethalPerformancePatcher.OnModsLoaded += LethalPerformancePatcher_OnModsLoaded;
		}

		private void LethalPerformancePatcher_OnModsLoaded()
		{
			DiageticVoiceMixerNative.Initialize();
			if (Patch_VoiceController.ShouldPatch())
			{
				m_Harmony.PatchAll(typeof(Patch_VoiceController));
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "DiFFoZTweaks";

		public const string PLUGIN_NAME = "DiFFoZTweaks";

		public const string PLUGIN_VERSION = "1.7.2";
	}
}
namespace DiFFoZTweaks.Utilities
{
	internal static class HarmonyExceptionHandler
	{
		public static Exception? ReportException(Exception? exception)
		{
			if (exception != null)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)exception);
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)Environment.StackTrace);
			}
			return null;
		}
	}
}
namespace DiFFoZTweaks.Patches
{
	[HarmonyPatch(typeof(AudioReverbTrigger))]
	internal static class Patch_AudioReverbTrigger
	{
		[HarmonyCleanup]
		public static Exception? Cleanup(Exception exception)
		{
			return HarmonyExceptionHandler.ReportException(exception);
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void ValidateAudioSources(AudioReverbTrigger __instance)
		{
			if (__instance.audioChanges == null)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogError((object)("AudioChanges is null\nAudioReverbTrigger scene path: " + ((Component)__instance).transform.GetScenePath()));
				return;
			}
			switchToAudio[] audioChanges = __instance.audioChanges;
			foreach (switchToAudio val in audioChanges)
			{
				if (!((Object)(object)val.audio != (Object)null))
				{
					DiFFoZTweaksPlugin.Instance.Logger.LogError((object)("AudioReverbTrigger contains null AudioSource. Please report it to the moon developer\nAudioReverbTrigger scene path: " + ((Component)__instance).transform.GetScenePath()));
					break;
				}
			}
		}

		[HarmonyPatch("ChangeAudioReverbForPlayer")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CheckAudioSourceExists(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			int pos = val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && i.operand is FieldInfo fieldInfo && fieldInfo.FieldType == typeof(AudioSource)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Stloc_S && i.operand is LocalBuilder localBuilder && localBuilder.LocalType == typeof(AudioSource)), "audioSource")
			}).ThrowIfInvalid("Failed to find stloc of AudioSource").Advance(1)
				.Pos;
			object operand = val.NamedMatch("audioSource").operand;
			object operand2 = val.SearchForward((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Br)).ThrowIfInvalid("Failed to find for move next label").Operand;
			val.Start().Advance(pos).Insert((CodeInstruction[])(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Ldloc, operand),
				new CodeInstruction(OpCodes.Ldnull, (object)null),
				new CodeInstruction(OpCodes.Call, (object)typeof(Object).GetMethod("op_Equality", AccessTools.all)),
				new CodeInstruction(OpCodes.Brtrue, operand2)
			});
			return val.Instructions();
		}
	}
	[HarmonyPatch]
	internal static class Patch_DeferredMessageManager
	{
		private static readonly Dictionary<(Type type, uint rpcMethodId), string> s_RpcNames = new Dictionary<(Type, uint), string>();

		[HarmonyPatch(typeof(NetworkBehaviour), "__registerRpc")]
		[HarmonyPostfix]
		public static void CaptureRpcName(NetworkBehaviour __instance, uint hash, string rpcMethodName)
		{
			try
			{
				if (!string.IsNullOrEmpty(rpcMethodName))
				{
					s_RpcNames[(((object)__instance).GetType(), hash)] = rpcMethodName;
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendServerRpc")]
		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendClientRpc")]
		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendRpc")]
		[HarmonyPrefix]
		public static void LogEveryRpcSend(NetworkBehaviour __instance, uint rpcMethodId, ref FastBufferWriter bufferWriter, RpcDelivery rpcDelivery, MethodBase __originalMethod)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool flag = default(bool);
				if (DiFFoZTweaksPlugin.Instance.Config.LoggingConfig.LogEveryRpc.TryGetValue(ref flag) && flag)
				{
					Type type = ((object)__instance).GetType();
					DiFFoZTweaksPlugin.Instance.Logger.LogInfo((object)(type.Name + " (" + type.Assembly.GetName().Name + ") sending " + GetRpcKind(__originalMethod.Name) + " " + $"{ResolveRpc(__instance, rpcMethodId)} hash:{rpcMethodId} " + $"id:{__instance.NetworkObjectId} behaviour:{__instance.NetworkBehaviourId} " + $"spawned:{__instance.IsSpawned} delivery:{rpcDelivery} size:{((FastBufferWriter)(ref bufferWriter)).Length} " + "path:" + ((Component)__instance).transform.GetScenePath()));
					bool flag2 = default(bool);
					if (DiFFoZTweaksPlugin.Instance.Config.LoggingConfig.LogStacktrace.TryGetValue(ref flag2) && flag2)
					{
						DiFFoZTweaksPlugin.Instance.Logger.LogInfo((object)Environment.StackTrace);
					}
				}
			}
			catch (Exception arg)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)$"Failed to log RPC send\n{arg}");
			}
		}

		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendServerRpc")]
		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendClientRpc")]
		[HarmonyPatch(typeof(NetworkBehaviour), "__endSendRpc")]
		[HarmonyPostfix]
		public static void LogUnspawnedRpcSend(NetworkBehaviour __instance, uint rpcMethodId)
		{
			try
			{
				if (!__instance.IsSpawned || __instance.NetworkObjectId == 0L)
				{
					DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)$"{((object)__instance).GetType().Name} ({((object)__instance).GetType().Assembly.GetName().Name}) sent RPC {ResolveRpc(rpcMethodId)} while not spawned (id:{__instance.NetworkObjectId}, path:{((Component)__instance).transform.GetScenePath()})");
					bool flag = default(bool);
					if (DiFFoZTweaksPlugin.Instance.Config.LoggingConfig.LogStacktrace.TryGetValue(ref flag) && flag)
					{
						DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)Environment.StackTrace);
					}
				}
			}
			catch (Exception arg)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)$"Failed to log unspawned RPC send\n{arg}");
			}
		}

		[HarmonyPatch(typeof(DeferredMessageManager), "PurgeTrigger")]
		[HarmonyPrefix]
		public static void LogPurgedDeferredMessages(TriggerInfo triggerInfo)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00d0: 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)
			try
			{
				ManualLogSource logger = DiFFoZTweaksPlugin.Instance.Logger;
				for (int i = 0; i < triggerInfo.TriggerData.Length; i++)
				{
					TriggerData val = triggerInfo.TriggerData[i];
					Type messageType = GetMessageType(val.Header.MessageType);
					string text = messageType?.Name ?? $"Unknown({val.Header.MessageType})";
					if (TryReadRpcMetadata(val.Reader, messageType, out var metadata, out var rpcSenderClientId))
					{
						logger.LogWarning((object)($"[{i}] {text} sender:{val.SenderId} rpcSender:{rpcSenderClientId} " + $"objectId:{metadata.NetworkObjectId} behaviourId:{metadata.NetworkBehaviourId} " + $"rpc:{ResolveRpc(metadata.NetworkRpcMethodId)} hash:{metadata.NetworkRpcMethodId}"));
					}
					else
					{
						logger.LogWarning((object)$"[{i}] {text} sender:{val.SenderId} size:{val.Header.MessageSize}");
					}
				}
			}
			catch (Exception arg)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)$"Failed to check purged messages\n{arg}");
			}
		}

		private static bool TryReadRpcMetadata(FastBufferReader reader, Type? messageType, out RpcMetadata metadata, out ulong rpcSenderClientId)
		{
			//IL_0001: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			metadata = default(RpcMetadata);
			rpcSenderClientId = 0uL;
			if (messageType != typeof(ServerRpcMessage) && messageType != typeof(ClientRpcMessage) && messageType != typeof(RpcMessage))
			{
				return false;
			}
			if (messageType == typeof(RpcMessage))
			{
				ByteUnpacker.ReadValuePacked(reader, ref rpcSenderClientId);
			}
			ByteUnpacker.ReadValueBitPacked(reader, ref metadata.NetworkObjectId);
			ByteUnpacker.ReadValueBitPacked(reader, ref metadata.NetworkBehaviourId);
			ByteUnpacker.ReadValueBitPacked(reader, ref metadata.NetworkRpcMethodId);
			return true;
		}

		private static Type? GetMessageType(uint messageType)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			object obj;
			if (singleton == null)
			{
				obj = null;
			}
			else
			{
				NetworkMessageManager messageManager = singleton.MessageManager;
				obj = ((messageManager != null) ? messageManager.MessageTypes : null);
			}
			Type[] array = (Type[])obj;
			if (array == null || messageType >= array.Length)
			{
				return null;
			}
			return array[messageType];
		}

		private static string GetRpcKind(string methodName)
		{
			return methodName switch
			{
				"__endSendServerRpc" => "ServerRpc", 
				"__endSendClientRpc" => "ClientRpc", 
				"__endSendRpc" => "Rpc", 
				_ => methodName, 
			};
		}

		private static string ResolveRpc(NetworkBehaviour behaviour, uint rpcMethodId)
		{
			Type type = ((object)behaviour).GetType();
			while (type != null)
			{
				if (s_RpcNames.TryGetValue((type, rpcMethodId), out string value))
				{
					return type.Name + "." + value;
				}
				if (type == typeof(NetworkBehaviour))
				{
					break;
				}
				type = type.BaseType;
			}
			return ResolveRpc(rpcMethodId);
		}

		private static string ResolveRpc(uint rpcMethodId)
		{
			List<(Type, string)> list = new List<(Type, string)>();
			foreach (KeyValuePair<Type, Dictionary<uint, RpcReceiveHandler>> item in NetworkBehaviour.__rpc_func_table)
			{
				if (item.Value.ContainsKey(rpcMethodId) && s_RpcNames.TryGetValue((item.Key, rpcMethodId), out string value))
				{
					list.Add((item.Key, value));
				}
			}
			if (list.Count <= 0)
			{
				return $"??? ({rpcMethodId})";
			}
			return FormatRpcNames(list);
		}

		private static string FormatRpcNames(List<(Type behaviourType, string rpc)> names)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < names.Count; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append(names[i].behaviourType.Name).Append('.').Append(names[i].rpc);
			}
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch(typeof(FacepunchTransport))]
	internal static class Patch_FacepunchTransport
	{
		private static readonly ManualLogSource s_Logger = Logger.CreateLogSource("FacepunchTransport");

		[HarmonyCleanup]
		public static Exception? Cleanup(Exception exception)
		{
			return HarmonyExceptionHandler.ReportException(exception);
		}

		[HarmonyPatch("Send")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> LogSendMessageResult(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && i.operand is MethodInfo methodInfo && methodInfo.Name == "SendMessage"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Pop, (object)null, (string)null)
			}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher m)
			{
				m.Set(OpCodes.Call, (object)new Action<int>(LogSendResult).Method);
			}, (Action<string>)null);
			return val.Instructions();
		}

		private unsafe static void LogSendResult(int result)
		{
			//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_0004: Invalid comparison between Unknown and I4
			Result val = (Result)result;
			if ((int)val != 1)
			{
				s_Logger.LogWarning((object)("Send message returned not ok status: " + ((object)(*(Result*)(&val))/*cast due to .constrained prefix*/).ToString()));
			}
		}
	}
	[HarmonyPatch(typeof(MaterialReplacer))]
	internal static class Patch_MaterialReplacer
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool NoGlobalReplacers(out IEnumerable<IMaterialReplacer> __result)
		{
			__result = Array.Empty<IMaterialReplacer>();
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkObject))]
	internal static class Patch_NetworkObject
	{
		[HarmonyPatch("OnDestroy")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> LogObjectOnFailedDestroy(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"[Invalid Destroy][{0}][NetworkObjectId:{1}] Destroy a spawned {2} on a non-host client is not valid. Call {3} or {4} on the server/host instead.", (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((LambdaExpression)(Expression<Func<Action<NetworkObject>>>)(() => LogStacktrace)))
			});
			return val.Instructions();
		}

		public static void LogStacktrace(NetworkObject @object)
		{
			ManualLogSource logger = DiFFoZTweaksPlugin.Instance.Logger;
			try
			{
				logger.LogWarning((object)((Object)((Component)@object).gameObject).name);
			}
			catch
			{
			}
			try
			{
				logger.LogWarning((object)((object)@object).ToString());
			}
			catch
			{
			}
			try
			{
				Component[] components = ((Component)@object).GetComponents<Component>();
				Component[] array = components;
				foreach (Component val in array)
				{
					logger.LogWarning((object)GeneralExtensions.FullDescription(((object)val).GetType()));
				}
			}
			catch
			{
			}
			try
			{
				logger.LogWarning((object)((Component)@object).transform.GetScenePath());
			}
			catch
			{
			}
			try
			{
				bool flag = default(bool);
				if (DiFFoZTweaksPlugin.Instance.Config.LoggingConfig.LogStacktrace.TryGetValue(ref flag) && flag)
				{
					logger.LogWarning((object)Environment.StackTrace);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(PreInitSceneScript))]
	internal static class Patch_PreInitSceneScript
	{
		[HarmonyPatch("SetLaunchPanelsEnabled")]
		[HarmonyPostfix]
		internal static void FlashTaskbar()
		{
			if (DiFFoZTweaksPlugin.Instance.Config.FlashTaskbar.Value)
			{
				HWND activeWindow = PInvoke.GetActiveWindow();
				FLASHWINFO pfwi = new FLASHWINFO
				{
					cbSize = (uint)Marshal.SizeOf<FLASHWINFO>(),
					hwnd = activeWindow,
					dwFlags = (FLASHWINFO_FLAGS.FLASHW_ALL | FLASHWINFO_FLAGS.FLASHW_TIMERNOFG),
					uCount = uint.MaxValue,
					dwTimeout = 0u
				};
				PInvoke.FlashWindowEx(in pfwi);
			}
		}
	}
}
namespace DiFFoZTweaks.MoreCompany
{
	[HarmonyPatch]
	internal static class Patch_CosmeticApplication
	{
		private static readonly MethodBase? s_ApplyCosmetic;

		static Patch_CosmeticApplication()
		{
			if (!Dependencies.TryGetMod("me.swipez.melonloader.morecompany", out PluginInfo pluginInfo))
			{
				return;
			}
			Type type = ((object)pluginInfo.Instance).GetType().Assembly.GetType("MoreCompany.Cosmetics.CosmeticApplication");
			if (type == null)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)"Failed to find CosmeticApplication");
				return;
			}
			s_ApplyCosmetic = type.GetMethod("ApplyCosmetic", AccessTools.all);
			if (s_ApplyCosmetic == null)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogWarning((object)"Failed to find ApplyCosmetic");
			}
		}

		[HarmonyCleanup]
		public static Exception? Cleanup(Exception exception)
		{
			return HarmonyExceptionHandler.ReportException(exception);
		}

		[HarmonyPrepare]
		internal static bool ShouldPatch()
		{
			return s_ApplyCosmetic != null;
		}

		[HarmonyTargetMethod]
		internal static MethodBase GetTargetMethod()
		{
			return s_ApplyCosmetic;
		}

		[HarmonyPrefix]
		public static bool CheckCosmeticLimit(MonoBehaviour __instance, List<string> ___spawnedCosmeticsIds, out bool __result)
		{
			int num = default(int);
			if (!DiFFoZTweaksPlugin.Instance.Config.MoreCompany.CosmeticLimit.TryGetValue(ref num) || num < 0)
			{
				__result = false;
				return true;
			}
			PlayerControllerB componentInParent = ((Component)__instance).GetComponentInParent<PlayerControllerB>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				__result = false;
				return true;
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)componentInParent)
			{
				__result = false;
				return true;
			}
			if (___spawnedCosmeticsIds.Count + 1 > num)
			{
				DiFFoZTweaksPlugin.Instance.Logger.LogMessage((object)$"Ignoring cosmetic spawn for {componentInParent.playerUsername} due to reaching the limit of {num} cosmetics");
				__result = false;
				return false;
			}
			__result = false;
			return true;
		}
	}
}
namespace DiFFoZTweaks.MelaniesVoice
{
	internal static class Patch_VoiceController
	{
		[HarmonyCleanup]
		private static Exception? Cleanup(Exception exception)
		{
			return HarmonyExceptionHandler.ReportException(exception);
		}

		public static bool ShouldPatch()
		{
			PluginInfo pluginInfo;
			return Dependencies.TryGetMod("com.github.zehsteam.MelaniesVoice", out pluginInfo);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		[HarmonyPatch(typeof(VoiceController), "ApplySettings")]
		[HarmonyPostfix]
		private static void ApplyMixers(VoiceController __instance)
		{
			AudioMixerGroup val = SoundManager.Instance.playerVoiceMixers[__instance.PlayerScript.playerClientId];
			if (!((Object)(object)val == (Object)null))
			{
				PlayerAudioGroup playerAudioGroup = __instance.PlayerAudioGroup;
				playerAudioGroup.VoiceAudio.outputAudioMixerGroup = val;
				playerAudioGroup.DeadAudio.outputAudioMixerGroup = val;
			}
		}
	}
}
namespace DiFFoZTweaks.Extensions
{
	internal static class TransformExtension
	{
		public static string GetScenePath(this Transform transform)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('/').Append(((Object)transform).name);
			while ((Object)(object)(transform = transform.parent) != (Object)null)
			{
				stringBuilder.Insert(0, ((Object)transform).name).Insert(0, '/');
			}
			return stringBuilder.ToString();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/plugins/DiFFoZTweaks/DiFFoZTweaks.Patcher.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiFFoZTweaks.Patcher.Configuration;
using DiFFoZTweaks.Patcher.Configuration.Configs;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;

[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("DiFFoZTweaks.Patcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.2.0")]
[assembly: AssemblyInformationalVersion("1.7.2+0b8a86f142277342d1cab6aaa46c38f8911c9c65")]
[assembly: AssemblyProduct("DiFFoZTweaks.Patcher")]
[assembly: AssemblyTitle("DiFFoZTweaks.Patcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
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 DiFFoZTweaks.Patcher
{
	public class DiFFoZTweaksPatcher
	{
		private ConfigFile m_ConfigFile;

		public static IEnumerable<string> TargetDLLs { get; } = new <>z__ReadOnlySingleElementList<string>("Assembly-CSharp.dll");

		public static DiFFoZTweaksPatcher Instance { get; private set; } = null;

		public Harmony Harmony { get; private set; }

		public ManualLogSource Logger { get; private set; }

		public ConfigManager Config { get; private set; }

		public static void Initialize()
		{
			Instance = new DiFFoZTweaksPatcher();
			Instance.InternalInitialize();
		}

		private void InternalInitialize()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Logger = Logger.CreateLogSource("DiFFoZTweaksPatcher");
			string text = Path.Combine(Paths.ConfigPath, "DiFFoZTweaks.cfg");
			m_ConfigFile = new ConfigFile(text, true);
			Config = new ConfigManager(m_ConfigFile);
		}

		public static void Finish()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			DiFFoZTweaksPatcher instance = Instance;
			instance.Harmony = new Harmony("DiFFoZTweaksPatcher");
			instance.Harmony.PatchAll(typeof(DiFFoZTweaksPatcher).Assembly);
		}

		public static void Patch(AssemblyDefinition assembly)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition type = assembly.MainModule.GetType("", "AudioReverbTrigger");
			if (!((IEnumerable<MethodDefinition>)type.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "Start"))
			{
				MethodDefinition val = new MethodDefinition("Start", (MethodAttributes)129, assembly.MainModule.ImportReference(typeof(void)));
				ILProcessor iLProcessor = val.Body.GetILProcessor();
				for (int num = 0; num < 32; num++)
				{
					iLProcessor.Append(Instruction.Create(OpCodes.Nop));
				}
				iLProcessor.Append(Instruction.Create(OpCodes.Ret));
				type.Methods.Add(val);
			}
		}
	}
}
namespace DiFFoZTweaks.Patcher.Patches
{
	[HarmonyPatch(typeof(Chainloader))]
	internal static class Patch_Chainloader
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		public static void PatchAfterUnity()
		{
			DiFFoZTweaksPatcher.Instance.Harmony.CreateProcessor((MethodBase)AccessTools.Method(typeof(Chainloader), "Start", (Type[])null, (Type[])null)).AddTranspiler(SymbolExtensions.GetMethodInfo((Expression<Action>)(() => PatchPluginTranspiler(null)))).Patch();
		}

		[HarmonyPatch("ToPluginInfo")]
		[HarmonyPostfix]
		public static void CheckIfPluginIgnored(ref PluginInfo? __result)
		{
			if (__result == null)
			{
				return;
			}
			BepInExConfig bepInExConfig = DiFFoZTweaksPatcher.Instance.Config.BepInExConfig;
			if (!bepInExConfig.Enabled.Value)
			{
				return;
			}
			string[] value = bepInExConfig.PluginsToNotLoad.Value.Value;
			if (value.Length == 0)
			{
				return;
			}
			string[] array = value;
			foreach (string text in array)
			{
				ReadOnlySpan<char> span = text.AsSpan().Trim();
				if (span.SequenceEqual(__result.Metadata.GUID))
				{
					DiFFoZTweaksPatcher.Instance.Logger.LogMessage((object)("Ignoring loading of " + __result.Metadata.Name));
					__result = null;
					break;
				}
			}
		}

		public static IEnumerable<CodeInstruction> PatchPluginTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, "pluginInfo"),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, "assembly"),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, "assemblyLoadedLabel")
			}).GetNamedMatchOperand<LocalBuilder>("pluginInfo", out var result).GetNamedMatchOperand<LocalBuilder>("assembly", out var result2)
				.GetNamedMatchOperand<Label>("assemblyLoadedLabel", out var result3)
				.Insert((CodeInstruction[])(object)new CodeInstruction[4]
				{
					new CodeInstruction(OpCodes.Ldloc, (object)result),
					new CodeInstruction(OpCodes.Ldloca, (object)result2),
					new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo<Assembly, bool>((Expression<Func<Assembly, bool>>)((Assembly b) => PatchPlugin(null, out b)))),
					new CodeInstruction(OpCodes.Brtrue, (object)result3)
				});
			return val.Instructions();
		}

		private static bool PatchPlugin(PluginInfo info, out Assembly? assembly)
		{
			assembly = null;
			return false;
		}

		private static bool IsLdLoc(CodeInstruction instruction)
		{
			return CodeInstructionExtensions.IsLdloc(instruction, (LocalBuilder)null);
		}

		private static CodeMatcher GetNamedMatchOperand<T>(this CodeMatcher matcher, string name, out T result)
		{
			result = (T)matcher.NamedMatch(name).operand;
			return matcher;
		}
	}
}
namespace DiFFoZTweaks.Patcher.Configuration
{
	public static class ConfigEntryCheck
	{
		public static ConfigEntryCheck<T> Bind<T>(this ConfigFile config, ConfigEntry<bool> enabledEntry, string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = config.Bind<T>(section, key, defaultValue, description);
			return new ConfigEntryCheck<T>(enabledEntry, configEntry);
		}

		public static LazyConfigEntryCheck<T, U> BindLazy<T, U>(this ConfigFile config, ConfigEntry<bool> enabledEntry, Func<T, U> parser, string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = config.Bind<T>(section, key, defaultValue, description);
			return new LazyConfigEntryCheck<T, U>(enabledEntry, configEntry, parser);
		}
	}
	public class ConfigEntryCheck<T>
	{
		protected readonly ConfigEntry<bool> m_EnabledEntry;

		protected readonly ConfigEntry<T> m_ConfigEntry;

		public ConfigEntryCheck(ConfigEntry<bool> enabledEntry, ConfigEntry<T> configEntry)
		{
			m_EnabledEntry = enabledEntry;
			m_ConfigEntry = configEntry;
		}

		public bool TryGetValue(out T? value)
		{
			if (!m_EnabledEntry.Value)
			{
				value = default(T);
				return false;
			}
			value = m_ConfigEntry.Value;
			return true;
		}

		public void SubscribeAndInvoke(Action<ConfigEntryCheck<T>> action)
		{
			m_EnabledEntry.SettingChanged += EventHandler;
			m_ConfigEntry.SettingChanged += EventHandler;
			action(this);
			void EventHandler(object _, EventArgs __)
			{
				action(this);
			}
		}
	}
	public class ConfigManager
	{
		private readonly ConfigFile m_ConfigFile;

		public ConfigEntry<bool> FlashTaskbar { get; private set; }

		public MoreCompanyConfig MoreCompany { get; private set; }

		public BepInExConfig BepInExConfig { get; private set; }

		public LoggingConfig LoggingConfig { get; private set; }

		public ConfigManager(ConfigFile configFile)
		{
			m_ConfigFile = configFile;
			Initialize();
		}

		private void Initialize()
		{
			FlashTaskbar = m_ConfigFile.Bind<bool>("Utilities", "Flash taskbar after load", true, "Flash taskbar app when game loaded and waiting user input");
			MoreCompany = new MoreCompanyConfig(m_ConfigFile);
			BepInExConfig = new BepInExConfig(m_ConfigFile);
			LoggingConfig = new LoggingConfig(m_ConfigFile);
		}
	}
	public abstract class ConfigSection
	{
		private readonly ConfigFile m_Config;

		public string Section { get; }

		public ConfigEntry<bool> Enabled { get; protected set; }

		protected ConfigSection(ConfigFile config, string section, bool isEnabled = true, string enabledDescription = "Enable integration with the mod")
		{
			m_Config = config;
			Section = section;
			Enabled = config.Bind<bool>(section, "Enabled", isEnabled, enabledDescription);
			Initialize(config);
		}

		protected abstract void Initialize(ConfigFile config);

		protected ConfigEntryCheck<T> Bind<T>(string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = m_Config.Bind<T>(Section, key, defaultValue, description);
			return new ConfigEntryCheck<T>(Enabled, configEntry);
		}
	}
	public class LazyConfigEntryCheck<T, U> : ConfigEntryCheck<T>
	{
		private readonly Func<T, U> m_Parser;

		public Lazy<U> Value { get; private set; }

		public LazyConfigEntryCheck(ConfigEntry<bool> enabledEntry, ConfigEntry<T> configEntry, Func<T, U> parser)
			: base(enabledEntry, configEntry)
		{
			m_Parser = parser;
			Value = new Lazy<U>(ParseValue, isThreadSafe: true);
		}

		private U ParseValue()
		{
			return m_Parser(m_ConfigEntry.Value);
		}
	}
}
namespace DiFFoZTweaks.Patcher.Configuration.Configs
{
	public class BepInExConfig : ConfigSection
	{
		public LazyConfigEntryCheck<string, string[]> PluginsToNotLoad { get; private set; }

		public BepInExConfig(ConfigFile config)
			: base(config, "General - BepInEx", isEnabled: false, "Should patch BepInEx")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			PluginsToNotLoad = config.BindLazy(base.Enabled, ParseAsArray, base.Section, "Plugins to not load", "", "A list of GUID plugins that should be not loaded. Separator: ','.\nNote: BepInEx caches plugins metadata, so if you add or remove plugin here you should delete cache folder in the profile path.\n\nExample: TestAccount666.ShipWindows, LethalPerformance");
		}

		private static string[] ParseAsArray(string input)
		{
			return input.Split(',', StringSplitOptions.RemoveEmptyEntries);
		}
	}
	public class LoggingConfig : ConfigSection
	{
		public ConfigEntryCheck<bool> LogStacktrace { get; private set; }

		public ConfigEntryCheck<bool> LogEveryRpc { get; private set; }

		public LoggingConfig(ConfigFile config)
			: base(config, "Logging - Global Switch", isEnabled: true, "Enables the section of verbose logging")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			LogStacktrace = config.Bind(base.Enabled, base.Section, "Log StackTraces", defaultValue: false, "Log stacktraces where it's needed for debugging");
			LogEveryRpc = config.Bind(base.Enabled, base.Section, "Log Every RPC", defaultValue: false, "Log every RPC being sent. This is very verbose and should only be enabled for debugging");
		}
	}
	public class MoreCompanyConfig : ConfigSection
	{
		public ConfigEntryCheck<int> CosmeticLimit { get; private set; }

		public MoreCompanyConfig(ConfigFile config)
			: base(config, "Mods - MoreCompany")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			CosmeticLimit = config.Bind(base.Enabled, base.Section, "Cosmetic Limit", 15, "Defines the maximum number of cosmetics that can be spawned for the player. Set the value to -1 to disable the limit");
		}
	}
}

BepInEx/patchers/DiFFoZTweaks/DiFFoZTweaks.Patcher.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiFFoZTweaks.Patcher.Configuration;
using DiFFoZTweaks.Patcher.Configuration.Configs;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;

[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("DiFFoZTweaks.Patcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.2.0")]
[assembly: AssemblyInformationalVersion("1.7.2+0b8a86f142277342d1cab6aaa46c38f8911c9c65")]
[assembly: AssemblyProduct("DiFFoZTweaks.Patcher")]
[assembly: AssemblyTitle("DiFFoZTweaks.Patcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
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 DiFFoZTweaks.Patcher
{
	public class DiFFoZTweaksPatcher
	{
		private ConfigFile m_ConfigFile;

		public static IEnumerable<string> TargetDLLs { get; } = new <>z__ReadOnlySingleElementList<string>("Assembly-CSharp.dll");

		public static DiFFoZTweaksPatcher Instance { get; private set; } = null;

		public Harmony Harmony { get; private set; }

		public ManualLogSource Logger { get; private set; }

		public ConfigManager Config { get; private set; }

		public static void Initialize()
		{
			Instance = new DiFFoZTweaksPatcher();
			Instance.InternalInitialize();
		}

		private void InternalInitialize()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Logger = Logger.CreateLogSource("DiFFoZTweaksPatcher");
			string text = Path.Combine(Paths.ConfigPath, "DiFFoZTweaks.cfg");
			m_ConfigFile = new ConfigFile(text, true);
			Config = new ConfigManager(m_ConfigFile);
		}

		public static void Finish()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			DiFFoZTweaksPatcher instance = Instance;
			instance.Harmony = new Harmony("DiFFoZTweaksPatcher");
			instance.Harmony.PatchAll(typeof(DiFFoZTweaksPatcher).Assembly);
		}

		public static void Patch(AssemblyDefinition assembly)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition type = assembly.MainModule.GetType("", "AudioReverbTrigger");
			if (!((IEnumerable<MethodDefinition>)type.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "Start"))
			{
				MethodDefinition val = new MethodDefinition("Start", (MethodAttributes)129, assembly.MainModule.ImportReference(typeof(void)));
				ILProcessor iLProcessor = val.Body.GetILProcessor();
				for (int num = 0; num < 32; num++)
				{
					iLProcessor.Append(Instruction.Create(OpCodes.Nop));
				}
				iLProcessor.Append(Instruction.Create(OpCodes.Ret));
				type.Methods.Add(val);
			}
		}
	}
}
namespace DiFFoZTweaks.Patcher.Patches
{
	[HarmonyPatch(typeof(Chainloader))]
	internal static class Patch_Chainloader
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		public static void PatchAfterUnity()
		{
			DiFFoZTweaksPatcher.Instance.Harmony.CreateProcessor((MethodBase)AccessTools.Method(typeof(Chainloader), "Start", (Type[])null, (Type[])null)).AddTranspiler(SymbolExtensions.GetMethodInfo((Expression<Action>)(() => PatchPluginTranspiler(null)))).Patch();
		}

		[HarmonyPatch("ToPluginInfo")]
		[HarmonyPostfix]
		public static void CheckIfPluginIgnored(ref PluginInfo? __result)
		{
			if (__result == null)
			{
				return;
			}
			BepInExConfig bepInExConfig = DiFFoZTweaksPatcher.Instance.Config.BepInExConfig;
			if (!bepInExConfig.Enabled.Value)
			{
				return;
			}
			string[] value = bepInExConfig.PluginsToNotLoad.Value.Value;
			if (value.Length == 0)
			{
				return;
			}
			string[] array = value;
			foreach (string text in array)
			{
				ReadOnlySpan<char> span = text.AsSpan().Trim();
				if (span.SequenceEqual(__result.Metadata.GUID))
				{
					DiFFoZTweaksPatcher.Instance.Logger.LogMessage((object)("Ignoring loading of " + __result.Metadata.Name));
					__result = null;
					break;
				}
			}
		}

		public static IEnumerable<CodeInstruction> PatchPluginTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, "pluginInfo"),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)IsLdLoc, "assembly"),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, "assemblyLoadedLabel")
			}).GetNamedMatchOperand<LocalBuilder>("pluginInfo", out var result).GetNamedMatchOperand<LocalBuilder>("assembly", out var result2)
				.GetNamedMatchOperand<Label>("assemblyLoadedLabel", out var result3)
				.Insert((CodeInstruction[])(object)new CodeInstruction[4]
				{
					new CodeInstruction(OpCodes.Ldloc, (object)result),
					new CodeInstruction(OpCodes.Ldloca, (object)result2),
					new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo<Assembly, bool>((Expression<Func<Assembly, bool>>)((Assembly b) => PatchPlugin(null, out b)))),
					new CodeInstruction(OpCodes.Brtrue, (object)result3)
				});
			return val.Instructions();
		}

		private static bool PatchPlugin(PluginInfo info, out Assembly? assembly)
		{
			assembly = null;
			return false;
		}

		private static bool IsLdLoc(CodeInstruction instruction)
		{
			return CodeInstructionExtensions.IsLdloc(instruction, (LocalBuilder)null);
		}

		private static CodeMatcher GetNamedMatchOperand<T>(this CodeMatcher matcher, string name, out T result)
		{
			result = (T)matcher.NamedMatch(name).operand;
			return matcher;
		}
	}
}
namespace DiFFoZTweaks.Patcher.Configuration
{
	public static class ConfigEntryCheck
	{
		public static ConfigEntryCheck<T> Bind<T>(this ConfigFile config, ConfigEntry<bool> enabledEntry, string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = config.Bind<T>(section, key, defaultValue, description);
			return new ConfigEntryCheck<T>(enabledEntry, configEntry);
		}

		public static LazyConfigEntryCheck<T, U> BindLazy<T, U>(this ConfigFile config, ConfigEntry<bool> enabledEntry, Func<T, U> parser, string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = config.Bind<T>(section, key, defaultValue, description);
			return new LazyConfigEntryCheck<T, U>(enabledEntry, configEntry, parser);
		}
	}
	public class ConfigEntryCheck<T>
	{
		protected readonly ConfigEntry<bool> m_EnabledEntry;

		protected readonly ConfigEntry<T> m_ConfigEntry;

		public ConfigEntryCheck(ConfigEntry<bool> enabledEntry, ConfigEntry<T> configEntry)
		{
			m_EnabledEntry = enabledEntry;
			m_ConfigEntry = configEntry;
		}

		public bool TryGetValue(out T? value)
		{
			if (!m_EnabledEntry.Value)
			{
				value = default(T);
				return false;
			}
			value = m_ConfigEntry.Value;
			return true;
		}

		public void SubscribeAndInvoke(Action<ConfigEntryCheck<T>> action)
		{
			m_EnabledEntry.SettingChanged += EventHandler;
			m_ConfigEntry.SettingChanged += EventHandler;
			action(this);
			void EventHandler(object _, EventArgs __)
			{
				action(this);
			}
		}
	}
	public class ConfigManager
	{
		private readonly ConfigFile m_ConfigFile;

		public ConfigEntry<bool> FlashTaskbar { get; private set; }

		public MoreCompanyConfig MoreCompany { get; private set; }

		public BepInExConfig BepInExConfig { get; private set; }

		public LoggingConfig LoggingConfig { get; private set; }

		public ConfigManager(ConfigFile configFile)
		{
			m_ConfigFile = configFile;
			Initialize();
		}

		private void Initialize()
		{
			FlashTaskbar = m_ConfigFile.Bind<bool>("Utilities", "Flash taskbar after load", true, "Flash taskbar app when game loaded and waiting user input");
			MoreCompany = new MoreCompanyConfig(m_ConfigFile);
			BepInExConfig = new BepInExConfig(m_ConfigFile);
			LoggingConfig = new LoggingConfig(m_ConfigFile);
		}
	}
	public abstract class ConfigSection
	{
		private readonly ConfigFile m_Config;

		public string Section { get; }

		public ConfigEntry<bool> Enabled { get; protected set; }

		protected ConfigSection(ConfigFile config, string section, bool isEnabled = true, string enabledDescription = "Enable integration with the mod")
		{
			m_Config = config;
			Section = section;
			Enabled = config.Bind<bool>(section, "Enabled", isEnabled, enabledDescription);
			Initialize(config);
		}

		protected abstract void Initialize(ConfigFile config);

		protected ConfigEntryCheck<T> Bind<T>(string key, T defaultValue, string description)
		{
			ConfigEntry<T> configEntry = m_Config.Bind<T>(Section, key, defaultValue, description);
			return new ConfigEntryCheck<T>(Enabled, configEntry);
		}
	}
	public class LazyConfigEntryCheck<T, U> : ConfigEntryCheck<T>
	{
		private readonly Func<T, U> m_Parser;

		public Lazy<U> Value { get; private set; }

		public LazyConfigEntryCheck(ConfigEntry<bool> enabledEntry, ConfigEntry<T> configEntry, Func<T, U> parser)
			: base(enabledEntry, configEntry)
		{
			m_Parser = parser;
			Value = new Lazy<U>(ParseValue, isThreadSafe: true);
		}

		private U ParseValue()
		{
			return m_Parser(m_ConfigEntry.Value);
		}
	}
}
namespace DiFFoZTweaks.Patcher.Configuration.Configs
{
	public class BepInExConfig : ConfigSection
	{
		public LazyConfigEntryCheck<string, string[]> PluginsToNotLoad { get; private set; }

		public BepInExConfig(ConfigFile config)
			: base(config, "General - BepInEx", isEnabled: false, "Should patch BepInEx")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			PluginsToNotLoad = config.BindLazy(base.Enabled, ParseAsArray, base.Section, "Plugins to not load", "", "A list of GUID plugins that should be not loaded. Separator: ','.\nNote: BepInEx caches plugins metadata, so if you add or remove plugin here you should delete cache folder in the profile path.\n\nExample: TestAccount666.ShipWindows, LethalPerformance");
		}

		private static string[] ParseAsArray(string input)
		{
			return input.Split(',', StringSplitOptions.RemoveEmptyEntries);
		}
	}
	public class LoggingConfig : ConfigSection
	{
		public ConfigEntryCheck<bool> LogStacktrace { get; private set; }

		public ConfigEntryCheck<bool> LogEveryRpc { get; private set; }

		public LoggingConfig(ConfigFile config)
			: base(config, "Logging - Global Switch", isEnabled: true, "Enables the section of verbose logging")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			LogStacktrace = config.Bind(base.Enabled, base.Section, "Log StackTraces", defaultValue: false, "Log stacktraces where it's needed for debugging");
			LogEveryRpc = config.Bind(base.Enabled, base.Section, "Log Every RPC", defaultValue: false, "Log every RPC being sent. This is very verbose and should only be enabled for debugging");
		}
	}
	public class MoreCompanyConfig : ConfigSection
	{
		public ConfigEntryCheck<int> CosmeticLimit { get; private set; }

		public MoreCompanyConfig(ConfigFile config)
			: base(config, "Mods - MoreCompany")
		{
		}

		protected override void Initialize(ConfigFile config)
		{
			CosmeticLimit = config.Bind(base.Enabled, base.Section, "Cosmetic Limit", 15, "Defines the maximum number of cosmetics that can be spawned for the player. Set the value to -1 to disable the limit");
		}
	}
}