using 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;
}
}
}
}