Decompiled source of DiFFoZTweaks v1.5.0
BepInEx/plugins/DiFFoZTweaks/DiFFoZTweaks.Patcher.dll
Decompiled a day agousing 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.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0+0eb1893d709c3aff43504daffe2c1d6b5bca84ef")] [assembly: AssemblyProduct("DiFFoZTweaks.Patcher")] [assembly: AssemblyTitle("DiFFoZTweaks.Patcher")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 i = 0; i < 32; i++) { 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) { Action<ConfigEntryCheck<T>> action2 = action; m_EnabledEntry.SettingChanged += EventHandler; m_ConfigEntry.SettingChanged += EventHandler; action2(this); void EventHandler(object _, EventArgs __) { action2(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 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); } } 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 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"); } } } 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(); } }
BepInEx/plugins/DiFFoZTweaks/DiFFoZTweaks.dll
Decompiled a day agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; 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.Patcher; using DiFFoZTweaks.Patcher.Configuration; using DiFFoZTweaks.Utilities; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Netcode.Transports.Facepunch; using SoftMasking; using Steamworks; using Steamworks.Data; using Unity.Netcode; using UnityEngine; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.UI.WindowsAndMessaging; [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")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0+0eb1893d709c3aff43504daffe2c1d6b5bca84ef")] [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.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 static bool TryGetMod(string id, out PluginInfo pluginInfo) { return Chainloader.PluginInfos.TryGetValue(id, out pluginInfo); } } [BepInPlugin("DiFFoZTweaks", "DiFFoZTweaks", "1.5.0")] [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); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "DiFFoZTweaks"; public const string PLUGIN_NAME = "DiFFoZTweaks"; public const string PLUGIN_VERSION = "1.5.0"; } } 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(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(); } [HarmonyPatch("NetworkDeliveryToSendType")] [HarmonyPrefix] public static bool NetworkDeliveryToSendTypeNoNagle(NetworkDelivery delivery, out SendType __result) { //IL_0000: 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_0018: Expected I4, but got Unknown //IL_001b: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) SendType val; switch (delivery - 1) { case 0: val = (SendType)1; break; case 1: case 3: val = (SendType)8; break; case 2: val = (SendType)9; break; default: val = (SendType)0; break; } __result = (SendType)(int)val; return false; } private 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)(ref val)).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(PreInitSceneScript))] internal static class Patch_PreInitSceneScript { [HarmonyPatch("SetLaunchPanelsEnabled")] [HarmonyPostfix] internal static void FlashTaskbar() { if (DiFFoZTweaksPlugin.Instance.Config.FlashTaskbar.Value) { HWND activeWindow = PInvoke.GetActiveWindow(); FLASHWINFO fLASHWINFO = default(FLASHWINFO); fLASHWINFO.cbSize = (uint)Marshal.SizeOf<FLASHWINFO>(); fLASHWINFO.hwnd = activeWindow; fLASHWINFO.dwFlags = FLASHWINFO_FLAGS.FLASHW_ALL | FLASHWINFO_FLAGS.FLASHW_TIMERNOFG; fLASHWINFO.uCount = uint.MaxValue; fLASHWINFO.dwTimeout = 0u; FLASHWINFO pfwi = fLASHWINFO; 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)) { Type type = ((object)pluginInfo.Instance).GetType().Assembly.GetType("MoreCompany.Cosmetics.CosmeticApplication"); if (!(type == null)) { s_ApplyCosmetic = type.GetMethod("ApplyCosmetic", AccessTools.all); } } } [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.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(); } } }
BepInEx/patchers/DiFFoZTweaks/DiFFoZTweaks.Patcher.dll
Decompiled a day agousing 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.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0+0eb1893d709c3aff43504daffe2c1d6b5bca84ef")] [assembly: AssemblyProduct("DiFFoZTweaks.Patcher")] [assembly: AssemblyTitle("DiFFoZTweaks.Patcher")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 i = 0; i < 32; i++) { 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) { Action<ConfigEntryCheck<T>> action2 = action; m_EnabledEntry.SettingChanged += EventHandler; m_ConfigEntry.SettingChanged += EventHandler; action2(this); void EventHandler(object _, EventArgs __) { action2(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 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); } } 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 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"); } } } 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(); } }