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 EndlessEnemy v4.0.0
EndlessEnemy.dll
Decompiled 2 days agousing System; using System.Collections.Generic; 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 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("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 EndlessEnemy { [BepInPlugin("REPO_JP.EndlessEnemy", "EndlessEnemy", "4.0.0")] public sealed class EndlessEnemyPlugin : BaseUnityPlugin { private const string PluginGuid = "REPO_JP.EndlessEnemy"; private const string PluginName = "EndlessEnemy"; private const string PluginVersion = "4.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> CheckIntervalSeconds; internal static ConfigEntry<float> AfterTriggerCooldownSeconds; internal static ConfigEntry<int> RespawnCount; internal static ConfigEntry<float> RespawnTimerSeconds; internal static ConfigEntry<bool> IgnoreAfterExtractionCompleted; internal static ConfigEntry<bool> DebugLogEnabled; private Harmony harmony; private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindConfig(); harmony = new Harmony("REPO_JP.EndlessEnemy"); harmony.PatchAll(); Log.LogInfo((object)"EndlessEnemy v4.0.0 loaded"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; } private void BindConfig() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod.このMODを有効にします"); CheckIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckIntervalSeconds", 5f, new ConfigDescription("Interval in seconds for checking whether alive enemies are zero.生きている敵が0体か確認する間隔", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), Array.Empty<object>())); AfterTriggerCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AfterTriggerCooldownSeconds", 20f, new ConfigDescription("Delay in seconds before the next zero-enemy check after respawn timers are shortened.リスポーンタイマー短縮後に次の敵0体確認まで待つ秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>())); RespawnCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RespawnCount", 1, new ConfigDescription("Number of despawned enemies whose respawn timer will be shortened.リスポーンタイマーを短縮するデスポーン中の敵数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); RespawnTimerSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RespawnTimerSeconds", 5f, new ConfigDescription("Respawn timer value in seconds applied to selected enemies.選択された敵に設定するリスポーンタイマー秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); IgnoreAfterExtractionCompleted = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IgnoreAfterExtractionCompleted", false, "Do not shorten enemy respawn timers after all extraction points are completed.すべての抽出ポイント完了後は敵のリスポーンタイマーを短縮しません"); DebugLogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogEnabled", false, "Log enemy names when their respawn timer is shortened.リスポーンタイマーを短縮した敵名をログ出力します"); } } [HarmonyPatch(typeof(EnemyDirector), "Update")] internal static class EnemyDirectorUpdatePatch { private static float nextCheckTime; private static int lastLevelGeneratorInstanceId; private static void Postfix(EnemyDirector __instance) { EnemyRespawnController.Tick(__instance, ref nextCheckTime, ref lastLevelGeneratorInstanceId); } } internal static class EnemyRespawnController { private static readonly FieldRef<EnemyParent, bool> SpawnedRef = AccessTools.FieldRefAccess<EnemyParent, bool>("Spawned"); internal static void Tick(EnemyDirector director, ref float nextCheckTime, ref int lastLevelGeneratorInstanceId) { try { if (Time.time < nextCheckTime) { return; } float num = Mathf.Max(0.5f, EndlessEnemyPlugin.CheckIntervalSeconds.Value); float num2 = Mathf.Max(0f, EndlessEnemyPlugin.AfterTriggerCooldownSeconds.Value); int targetCount = Mathf.Clamp(EndlessEnemyPlugin.RespawnCount.Value, 1, 20); float targetTimer = Mathf.Clamp(EndlessEnemyPlugin.RespawnTimerSeconds.Value, 1f, 60f); if (!EndlessEnemyPlugin.Enabled.Value) { nextCheckTime = Time.time + num; return; } nextCheckTime = Time.time + num; if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)director == (Object)null || director.enemiesSpawned == null || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) { return; } int instanceID = ((Object)LevelGenerator.Instance).GetInstanceID(); if (instanceID != lastLevelGeneratorInstanceId) { lastLevelGeneratorInstanceId = instanceID; nextCheckTime = Time.time + num; } else { if ((EndlessEnemyPlugin.IgnoreAfterExtractionCompleted.Value && (Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.allExtractionPointsCompleted) || HasAnySpawnedEnemy(director.enemiesSpawned)) { return; } List<EnemyParent> list = BuildRespawnCandidates(director.enemiesSpawned, targetTimer); if (list.Count != 0) { int num3 = ShortenShortestTimers(list, targetCount, targetTimer); if (num3 > 0) { nextCheckTime = Time.time + num2; } } } } catch (Exception arg) { EndlessEnemyPlugin.Log.LogError((object)$"EndlessEnemy error: {arg}"); nextCheckTime = Time.time + 5f; } } private static bool HasAnySpawnedEnemy(List<EnemyParent> enemies) { for (int i = 0; i < enemies.Count; i++) { EnemyParent val = enemies[i]; if (!((Object)(object)val == (Object)null) && IsSpawned(val)) { return true; } } return false; } private static List<EnemyParent> BuildRespawnCandidates(List<EnemyParent> enemies, float targetTimer) { List<EnemyParent> list = new List<EnemyParent>(); for (int i = 0; i < enemies.Count; i++) { EnemyParent val = enemies[i]; if (!((Object)(object)val == (Object)null) && !IsSpawned(val) && val.DespawnedTimer > targetTimer) { list.Add(val); } } return list; } private static int ShortenShortestTimers(List<EnemyParent> candidates, int targetCount, float targetTimer) { int num = 0; for (int i = 0; i < targetCount; i++) { int num2 = -1; float num3 = float.MaxValue; for (int j = 0; j < candidates.Count; j++) { EnemyParent val = candidates[j]; if (!((Object)(object)val == (Object)null) && !IsSpawned(val) && !(val.DespawnedTimer <= targetTimer) && val.DespawnedTimer < num3) { num3 = val.DespawnedTimer; num2 = j; } } if (num2 < 0) { break; } EnemyParent val2 = candidates[num2]; candidates.RemoveAt(num2); float despawnedTimer = val2.DespawnedTimer; val2.DespawnedTimerSet(targetTimer, false); num++; if (EndlessEnemyPlugin.DebugLogEnabled.Value) { EndlessEnemyPlugin.Log.LogInfo((object)$"Shortened enemy respawn timer: {GetEnemyName(val2)} {despawnedTimer:F1}s -> {targetTimer:F1}s"); } } return num; } private static bool IsSpawned(EnemyParent enemy) { return SpawnedRef.Invoke(enemy); } private static string GetEnemyName(EnemyParent enemy) { if ((Object)(object)enemy == (Object)null) { return "Unknown Enemy"; } if (!string.IsNullOrWhiteSpace(enemy.enemyName)) { return enemy.enemyName; } return ((Object)enemy).name; } } }