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 OnlyMaskedPlayerEnemies v1.0.1
com.github.zehsteam.OnlyMaskedPlayerEnemies.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; 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 HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using com.github.zehsteam.OnlyMaskedPlayerEnemies.Dependencies; using com.github.zehsteam.OnlyMaskedPlayerEnemies.Patches; [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: AssemblyCompany("com.github.zehsteam.OnlyMaskedPlayerEnemies")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("This mod will make only Masked Player Enemies spawn.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+75838dab1e333823f423656df26bc03233caafbb")] [assembly: AssemblyProduct("OnlyMaskedPlayerEnemies")] [assembly: AssemblyTitle("com.github.zehsteam.OnlyMaskedPlayerEnemies")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.OnlyMaskedPlayerEnemies { internal static class ConfigHelper { public static void SetModIcon(Sprite sprite) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModIcon(sprite); } } public static void SetModDescription(string description) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModDescription(description); } } public static void SkipAutoGen() { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SkipAutoGen(); } } public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (configFile == null) { configFile = ((BaseUnityPlugin)Plugin.Instance).Config; } ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>()))); if (settingChanged != null) { configEntry.SettingChanged += delegate { settingChanged?.Invoke(configEntry.Value); }; } if (LethalConfigProxy.Enabled) { if (acceptableValues == null) { LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart); } else { LethalConfigProxy.AddConfigSlider<T>(configEntry, requiresRestart); } } return configEntry; } public static void AddButton(string section, string name, string description, string buttonText, Action callback) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddButton(section, name, description, buttonText, callback); } } } internal class ConfigManager { public ConfigEntry<int> MaxSpawnCount { get; private set; } public ConfigEntry<bool> Hourly_Enabled { get; private set; } public ConfigEntry<int> Hourly_SpawnCount { get; private set; } public ConfigEntry<float> Hourly_SpawnChance { get; private set; } public ConfigManager() { BindConfigs(); SetupChangedEvents(); ClearUnusedEntries(); } private void BindConfigs() { ConfigHelper.SkipAutoGen(); MaxSpawnCount = ConfigHelper.Bind("Masked Player Enemy Settings", "MaxSpawnCount", 100, requiresRestart: false, "The max spawn count for Masked player enemies."); Hourly_Enabled = ConfigHelper.Bind("Hourly Spawn Settings", "Enabled", defaultValue: false, requiresRestart: false, "If enabled, Masked player enemies will force spawn hourly."); Hourly_SpawnCount = ConfigHelper.Bind("Hourly Spawn Settings", "SpawnCount", 4, requiresRestart: false, "The amount of Masked player enemies to try and spawn."); Hourly_SpawnChance = ConfigHelper.Bind("Hourly Spawn Settings", "SpawnChance", 50f, requiresRestart: false, "The percent chance a Masked player enemy will spawn hourly."); } private void SetupChangedEvents() { MaxSpawnCount.SettingChanged += MaxSpawnCount_SettingChanged; } private void MaxSpawnCount_SettingChanged(object sender, EventArgs e) { EnemyHelper.SetOnlyEnemyMasked(); } private void ClearUnusedEntries() { ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config; PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null); dictionary.Clear(); config.Save(); } } internal static class EnemyHelper { public static void SetOnlyEnemyMasked() { SetOnlyEnemy("Masked"); } public static void SetOnlyEnemy(string enemyName) { if (!((Object)(object)StartOfRound.Instance == (Object)null)) { SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel level in levels) { SetOnlyEnemyForLevel(level, enemyName, 10000, Plugin.ConfigManager.MaxSpawnCount.Value); } } } private static void SetOnlyEnemyForLevel(SelectableLevel level, string enemyName, int rarity, int maxSpawnCount) { SetOnlyEnemyForList(ref level.Enemies, enemyName, rarity, maxSpawnCount); SetOnlyEnemyForList(ref level.OutsideEnemies, enemyName, rarity, maxSpawnCount); } private static void SetOnlyEnemyForList(ref List<SpawnableEnemyWithRarity> spawnableEnemyWithRarities, string enemyName, int rarity, int maxSpawnCount) { bool flag = false; foreach (SpawnableEnemyWithRarity spawnableEnemyWithRarity in spawnableEnemyWithRarities) { if (spawnableEnemyWithRarity.enemyType.enemyName == enemyName) { flag = true; spawnableEnemyWithRarity.rarity = rarity; spawnableEnemyWithRarity.enemyType.MaxCount = maxSpawnCount; Plugin.logger.LogMessage((object)$"Set enemy \"{enemyName}\" rarity to {rarity}."); } else { spawnableEnemyWithRarity.rarity = 0; Plugin.logger.LogInfo((object)$"Set enemy \"{spawnableEnemyWithRarity.enemyType.enemyName}\" rarity to {spawnableEnemyWithRarity.rarity}."); } } if (!flag) { AddEnemyToList(ref spawnableEnemyWithRarities, enemyName, rarity, maxSpawnCount); } } private static void AddEnemyToList(ref List<SpawnableEnemyWithRarity> spawnableEnemyWithRarities, string enemyName, int rarity, int maxSpawnCount) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown EnemyType enemyType = GetEnemyType(enemyName); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)("Failed to add enemy \"" + enemyName + "\" to list.")); return; } SpawnableEnemyWithRarity val = new SpawnableEnemyWithRarity(); val.rarity = rarity; val.enemyType = enemyType; val.enemyType.MaxCount = maxSpawnCount; spawnableEnemyWithRarities.Add(val); Plugin.logger.LogInfo((object)("Added enemy \"" + enemyName + "\" to list.")); } public static void SpawnEnemyOnServer(string enemyName) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (!NetworkUtils.IsServer) { Plugin.logger.LogError((object)"Failed to spawn enemy. Only the host can spawn enemies."); return; } EnemyType enemyType = GetEnemyType(enemyName); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)("Failed to spawn \"" + enemyName + "\" enemy. EnemyType is null.")); return; } if ((Object)(object)enemyType.enemyPrefab == (Object)null) { Plugin.logger.LogError((object)("Failed to spawn \"" + enemyName + "\" enemy. EnemyType.enemyPrefab is null.")); return; } Plugin.logger.LogInfo((object)("Trying to spawn \"" + enemyName + "\" enemy.")); Vector3 randomSpawnPosition = GetRandomSpawnPosition(); float num = Random.Range(0f, 360f); RoundManager.Instance.SpawnEnemyGameObject(randomSpawnPosition, num, -1, enemyType); Plugin.logger.LogInfo((object)$"Spawned \"{enemyName}\" enemy at position: (x: {randomSpawnPosition.x}, y: {randomSpawnPosition.y}, z: {randomSpawnPosition.z})"); } private static Vector3 GetRandomSpawnPosition() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RoundManager.Instance == (Object)null) { return Vector3.zero; } if (Utils.RandomPercent(50f)) { return GetRandomSpawnPositionInside(); } return GetRandomSpawnPositionOutside(); } private static Vector3 GetRandomSpawnPositionInside() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (RoundManager.Instance.insideAINodes == null || RoundManager.Instance.insideAINodes.Length == 0) { return Vector3.zero; } GameObject[] array = RoundManager.Instance.insideAINodes.Where((GameObject _) => (Object)(object)_ != (Object)null).ToArray(); if (array.Length == 0) { return Vector3.zero; } return array[Random.Range(0, array.Length)].transform.position; } private static Vector3 GetRandomSpawnPositionOutside() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (RoundManager.Instance.outsideAINodes == null || RoundManager.Instance.outsideAINodes.Length == 0) { return Vector3.zero; } GameObject[] array = RoundManager.Instance.outsideAINodes.Where((GameObject _) => (Object)(object)_ != (Object)null).ToArray(); if (array.Length == 0) { return Vector3.zero; } return array[Random.Range(0, array.Length)].transform.position; } public static EnemyType GetEnemyType(string enemyName) { foreach (EnemyType enemyType in GetEnemyTypes()) { if (enemyType.enemyName == enemyName) { return enemyType; } } try { EnemyType val = Resources.FindObjectsOfTypeAll<EnemyType>().Single((EnemyType x) => x.enemyName == enemyName); if (IsValidEnemyType(val) && NetworkUtils.IsNetworkPrefab(val.enemyPrefab)) { Plugin.logger.LogInfo((object)("Found EnemyType \"" + val.enemyName + "\" from Resources.")); return val; } } catch { } return null; } public static List<EnemyType> GetEnemyTypes() { HashSet<EnemyType> hashSet = new HashSet<EnemyType>(new EnemyTypeComparer()); SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { IEnumerable<EnemyType> enumerable = (from e in val.Enemies.Concat(val.DaytimeEnemies).Concat(val.OutsideEnemies) select e.enemyType).Where(IsValidEnemyType); foreach (EnemyType item in enumerable) { hashSet.Add(item); } } return hashSet.ToList(); } public static bool IsValidEnemyType(EnemyType enemyType) { if ((Object)(object)enemyType == (Object)null) { return false; } if (string.IsNullOrWhiteSpace(enemyType.enemyName)) { return false; } if ((Object)(object)enemyType.enemyPrefab == (Object)null) { return false; } return true; } } public class EnemyTypeComparer : IEqualityComparer<EnemyType> { public bool Equals(EnemyType x, EnemyType y) { if ((Object)(object)x == (Object)null || (Object)(object)y == (Object)null) { return false; } return x.enemyName == y.enemyName; } public int GetHashCode(EnemyType obj) { return obj.enemyName?.GetHashCode() ?? 0; } } internal static class NetworkUtils { public static bool IsServer { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsServer; } } public static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton == (Object)null) { return false; } return NetworkManager.Singleton.IsHost; } } public static ulong GetLocalClientId() { return NetworkManager.Singleton.LocalClientId; } public static bool IsLocalClientId(ulong clientId) { return clientId == GetLocalClientId(); } public static bool IsNetworkPrefab(GameObject prefab) { foreach (NetworkPrefab prefab2 in NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs) { if ((Object)(object)prefab2.Prefab == (Object)(object)prefab) { return true; } } return false; } } [BepInPlugin("com.github.zehsteam.OnlyMaskedPlayerEnemies", "OnlyMaskedPlayerEnemies", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.github.zehsteam.OnlyMaskedPlayerEnemies"); internal static Plugin Instance; internal static ManualLogSource logger; internal static ConfigManager ConfigManager; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("com.github.zehsteam.OnlyMaskedPlayerEnemies"); logger.LogInfo((object)"OnlyMaskedPlayerEnemies has awoken!"); harmony.PatchAll(typeof(StartOfRoundPatch)); harmony.PatchAll(typeof(RoundManagerPatch)); ConfigManager = new ConfigManager(); } } internal static class Utils { public static bool RandomPercent(float percent) { if (percent <= 0f) { return false; } if (percent >= 100f) { return true; } return Random.value * 100f <= percent; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.OnlyMaskedPlayerEnemies"; public const string PLUGIN_NAME = "OnlyMaskedPlayerEnemies"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace com.github.zehsteam.OnlyMaskedPlayerEnemies.Patches { [HarmonyPatch(typeof(RoundManager))] internal static class RoundManagerPatch { [HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPostfix] private static void AdvanceHourAndSpawnNewBatchOfEnemiesPatch() { if (!NetworkUtils.IsServer || !Plugin.ConfigManager.Hourly_Enabled.Value) { return; } Plugin.logger.LogInfo((object)"Trying to force spawn Masked player enemies hourly."); EnemyType enemyType = EnemyHelper.GetEnemyType("Masked"); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)"Failed to force spawn Masked player enemies hourly. EnemyType is null."); return; } int value = Plugin.ConfigManager.Hourly_SpawnCount.Value; int value2 = Plugin.ConfigManager.MaxSpawnCount.Value; if (enemyType.numberSpawned >= value2) { Plugin.logger.LogWarning((object)$"Failed to force spawn Masked player enemies hourly. Max spawn count of {value2} has been reached."); return; } for (int i = 0; i < value; i++) { if (enemyType.numberSpawned >= value2) { Plugin.logger.LogWarning((object)$"Failed to force spawn Masked player enemies hourly. Max spawn count of {value2} has been reached."); break; } if (Utils.RandomPercent(Plugin.ConfigManager.Hourly_SpawnChance.Value)) { EnemyHelper.SpawnEnemyOnServer("Masked"); } } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { EnemyHelper.SetOnlyEnemyMasked(); } } } namespace com.github.zehsteam.OnlyMaskedPlayerEnemies.Dependencies { internal static class LethalConfigProxy { public const string PLUGIN_GUID = "ainavt.lc.lethalconfig"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetModIcon(Sprite sprite) { LethalConfigManager.SetModIcon(sprite); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetModDescription(string description) { LethalConfigManager.SetModDescription(description); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SkipAutoGen() { LethalConfigManager.SkipAutoGen(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (!(configEntry is ConfigEntry<string> val)) { if (!(configEntry is ConfigEntry<bool> val2)) { if (!(configEntry is ConfigEntry<float> val3)) { if (!(configEntry is ConfigEntry<int> val4)) { throw new NotSupportedException($"Unsupported type: {typeof(T)}"); } LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart)); } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart)); } } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart)); } } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (!(configEntry is ConfigEntry<float> val)) { if (!(configEntry is ConfigEntry<int> val2)) { throw new NotSupportedException($"Slider not supported for type: {typeof(T)}"); } LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart)); } else { LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddButton(string section, string name, string description, string buttonText, Action callback) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate { callback?.Invoke(); })); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }