Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Too Many Ducks v1.0.1
SoManyDucks.dll
Decompiled 8 months agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SoManyDucks")] [assembly: AssemblyTitle("SoManyDucks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 Empress.Ducks { [BepInPlugin("dev.empress.repo.empressducks", "Empress Ducks", "2.0.0")] public sealed class EmpressDucksPlugin : BaseUnityPlugin { public const string PluginGuid = "dev.empress.repo.empressducks"; public const string PluginName = "Empress Ducks"; public const string PluginVersion = "2.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> DuckCount; internal static ConfigEntry<bool> MasterOnly; private Harmony _harmony; internal static Object DuckSetupObj; internal static bool DuckSearchTriedThisRun; private static Type T_EnemyDirector; private static Type T_EnemySetup; private static Type T_LevelGenerator; private static Type T_RunManager; private static Type T_GameManager; private static Type T_EnemyDuck; private static MethodInfo M_AmountSetup; private static MethodInfo M_GetEnemy; private static MethodInfo M_EnemySpawn; private static MethodInfo M_EnemiesSpawnedRemoveStart; private static FieldInfo F_TotalAmount; private static FieldInfo F_EnemyList; private static FieldInfo F_EnemyListCurrent; private static FieldInfo F_EnemyListIndex; private static FieldInfo F_EnemiesDifficulty1; private static FieldInfo F_EnemiesDifficulty2; private static FieldInfo F_EnemiesDifficulty3; private static PropertyInfo P_Instance_EnemyDirector; private static PropertyInfo P_Instance_RunManager; private static MethodInfo M_GameManager_Multiplayer; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Expected O, but got Unknown //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable/disable Empress Ducks."); DuckCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "DuckCount", 200, new ConfigDescription("Number of ducks to spawn per level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>())); MasterOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Multiplayer", "MasterOnly", true, "Apply only on MasterClient to avoid desyncs."); _harmony = new Harmony("dev.empress.repo.empressducks"); T_EnemyDirector = AccessTools.TypeByName("EnemyDirector"); T_EnemySetup = AccessTools.TypeByName("EnemySetup"); T_LevelGenerator = AccessTools.TypeByName("LevelGenerator"); T_RunManager = AccessTools.TypeByName("RunManager"); T_GameManager = AccessTools.TypeByName("GameManager"); T_EnemyDuck = AccessTools.TypeByName("EnemyDuck"); if (T_EnemyDirector == null || T_EnemySetup == null || T_LevelGenerator == null || T_RunManager == null || T_GameManager == null) { Log.LogError((object)"[EmpressDucks] Required game types not found. Aborting patches."); return; } M_AmountSetup = AccessTools.Method(T_EnemyDirector, "AmountSetup", (Type[])null, (Type[])null); M_GetEnemy = AccessTools.Method(T_EnemyDirector, "GetEnemy", (Type[])null, (Type[])null); M_EnemySpawn = AccessTools.Method(T_LevelGenerator, "EnemySpawn", new Type[2] { T_EnemySetup, typeof(Vector3) }, (Type[])null); M_EnemiesSpawnedRemoveStart = AccessTools.Method(T_RunManager, "EnemiesSpawnedRemoveStart", (Type[])null, (Type[])null); F_TotalAmount = AccessTools.Field(T_EnemyDirector, "totalAmount"); F_EnemyList = AccessTools.Field(T_EnemyDirector, "enemyList"); F_EnemyListCurrent = AccessTools.Field(T_EnemyDirector, "enemyListCurrent"); F_EnemyListIndex = AccessTools.Field(T_EnemyDirector, "enemyListIndex"); F_EnemiesDifficulty1 = AccessTools.Field(T_EnemyDirector, "enemiesDifficulty1"); F_EnemiesDifficulty2 = AccessTools.Field(T_EnemyDirector, "enemiesDifficulty2"); F_EnemiesDifficulty3 = AccessTools.Field(T_EnemyDirector, "enemiesDifficulty3"); P_Instance_EnemyDirector = AccessTools.Property(T_EnemyDirector, "instance") ?? AccessTools.Property(T_EnemyDirector, "Instance"); P_Instance_RunManager = AccessTools.Property(T_RunManager, "instance") ?? AccessTools.Property(T_RunManager, "Instance"); M_GameManager_Multiplayer = AccessTools.Method(T_GameManager, "Multiplayer", Type.EmptyTypes, (Type[])null); if (M_EnemiesSpawnedRemoveStart != null) { HarmonyMethod val = new HarmonyMethod(typeof(EmpressDucksPlugin).GetMethod("Prefix_RunReset", BindingFlags.Static | BindingFlags.NonPublic)); _harmony.Patch((MethodBase)M_EnemiesSpawnedRemoveStart, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"[EmpressDucks] Patch OK -> RunManager.EnemiesSpawnedRemoveStart (cache reset)"); } else { Log.LogWarning((object)"[EmpressDucks] Could not find RunManager.EnemiesSpawnedRemoveStart"); } if (M_AmountSetup != null && F_TotalAmount != null) { HarmonyMethod val2 = new HarmonyMethod(typeof(EmpressDucksPlugin).GetMethod("Postfix_AmountSetup", BindingFlags.Static | BindingFlags.NonPublic)); _harmony.Patch((MethodBase)M_AmountSetup, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"[EmpressDucks] Patch OK -> EnemyDirector.AmountSetup (totalAmount override + duck cache)"); } else { Log.LogWarning((object)"[EmpressDucks] Could not patch EnemyDirector.AmountSetup"); } if (M_GetEnemy != null) { HarmonyMethod val3 = new HarmonyMethod(typeof(EmpressDucksPlugin).GetMethod("Prefix_GetEnemy", BindingFlags.Static | BindingFlags.NonPublic)); _harmony.Patch((MethodBase)M_GetEnemy, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"[EmpressDucks] Patch OK -> EnemyDirector.GetEnemy (force duck return)"); } else { Log.LogWarning((object)"[EmpressDucks] Could not patch EnemyDirector.GetEnemy"); } if (M_EnemySpawn != null) { HarmonyMethod val4 = new HarmonyMethod(typeof(EmpressDucksPlugin).GetMethod("Prefix_EnemySpawn", BindingFlags.Static | BindingFlags.NonPublic)); _harmony.Patch((MethodBase)M_EnemySpawn, val4, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"[EmpressDucks] Patch OK -> LevelGenerator.EnemySpawn (force duck param)"); } else { Log.LogWarning((object)"[EmpressDucks] Could not patch LevelGenerator.EnemySpawn"); } Log.LogInfo((object)"\r\n┌─────────────────────────────────┐\r\n│ ██████╗ ███╗ ███╗███╗ ██╗██╗│\r\n│██╔═══██╗████╗ ████║████╗ ██║██║│\r\n│██║ ██║██╔████╔██║██╔██╗ ██║██║│\r\n│██║ ██║██║╚██╔╝██║██║╚██╗██║██║│\r\n│╚██████╔╝██║ ╚═╝ ██║██║ ╚████║██║│\r\n│ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝│\r\n│ │\r\n│██████╗ ██╗ ██╗ ██████╗██╗ ██╗│\r\n│██╔══██╗██║ ██║██╔════╝██║ ██╔╝│\r\n│██║ ██║██║ ██║██║ █████╔╝ │\r\n│██║ ██║██║ ██║██║ ██╔═██╗ │\r\n│██████╔╝╚██████╔╝╚██████╗██║ ██╗│\r\n│╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝│\r\n└─────────────────────────────────┘\r\n"); Log.LogInfo((object)"Empress Ducks 2.0.0 loaded. Runtime name-bound patches armed."); } private static bool IsMasterAllowed() { try { if (!MasterOnly.Value) { return true; } if (M_GameManager_Multiplayer != null && (bool)M_GameManager_Multiplayer.Invoke(null, null)) { return PhotonNetwork.IsMasterClient; } return true; } catch { return true; } } private static void Prefix_RunReset() { DuckSetupObj = null; DuckSearchTriedThisRun = false; ManualLogSource log = Log; if (log != null) { log.LogDebug((object)"[EmpressDucks] Cache reset."); } } private static void Postfix_AmountSetup(object __instance) { if (!Enabled.Value || !IsMasterAllowed()) { return; } try { int num = Mathf.Max(1, DuckCount.Value); if (F_TotalAmount != null) { F_TotalAmount.SetValue(__instance, num); Log.LogInfo((object)$"[EmpressDucks] totalAmount -> {num}"); } TryCacheDuckSetupFromDirector(__instance); } catch (Exception arg) { Log.LogError((object)$"[EmpressDucks] AmountSetup postfix failed: {arg}"); } } private static bool Prefix_GetEnemy(object __instance, ref Object __result) { if (!Enabled.Value || !IsMasterAllowed()) { return true; } try { if (DuckSetupObj == (Object)null) { TryCacheDuckSetupFromDirector(__instance); } if (DuckSetupObj != (Object)null) { __result = DuckSetupObj; return false; } if (!DuckSearchTriedThisRun) { Log.LogWarning((object)"[EmpressDucks] No Duck EnemySetup found on director. Letting vanilla pick."); } DuckSearchTriedThisRun = true; return true; } catch (Exception arg) { Log.LogError((object)$"[EmpressDucks] GetEnemy prefix failed: {arg}"); return true; } } private static void Prefix_EnemySpawn(ref Object enemySetup) { if (!Enabled.Value || !IsMasterAllowed()) { return; } try { if (DuckSetupObj == (Object)null) { object obj = P_Instance_EnemyDirector?.GetValue(null, null); if (obj != null) { TryCacheDuckSetupFromDirector(obj); } } if (DuckSetupObj != (Object)null) { enemySetup = DuckSetupObj; } } catch (Exception arg) { Log.LogError((object)$"[EmpressDucks] EnemySpawn prefix failed: {arg}"); } } private static void TryCacheDuckSetupFromDirector(object director) { //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown if (director == null || T_EnemyDirector == null || T_EnemySetup == null) { return; } try { IEnumerable[] array = new IEnumerable[3] { F_EnemiesDifficulty1?.GetValue(director) as IEnumerable, F_EnemiesDifficulty2?.GetValue(director) as IEnumerable, F_EnemiesDifficulty3?.GetValue(director) as IEnumerable }; IEnumerable[] array2 = array; foreach (IEnumerable enumerable in array2) { if (enumerable == null) { continue; } foreach (object item in enumerable) { if (item == null || !(AccessTools.Field(T_EnemySetup, "spawnObjects")?.GetValue(item) is IEnumerable enumerable2)) { continue; } foreach (object item2 in enumerable2) { GameObject val = (GameObject)((item2 is GameObject) ? item2 : null); if (!((Object)(object)val == (Object)null)) { bool flag = false; if (T_EnemyDuck != null && (Object)(object)val.GetComponentInChildren(T_EnemyDuck, true) != (Object)null) { flag = true; } if (!flag && ((Object)val).name != null && ((Object)val).name.IndexOf("Duck", StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } if (flag) { DuckSetupObj = (Object)item; Log.LogInfo((object)("[EmpressDucks] Cached Duck setup: " + DuckSetupObj.name)); return; } } } } } } catch (Exception arg) { Log.LogError((object)$"[EmpressDucks] Duck cache scan failed: {arg}"); } finally { DuckSearchTriedThisRun = true; } } } }