Decompiled source of MultitudesWithoutPriceScale v1.1.1

plugins/MultitudesNoPriceScale.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using On.RoR2;
using On.RoR2.UI.MainMenu;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.Networking;

[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("MultitudesNoPriceScale")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+1616d0db1a1881ba62fbbd38f43cb8bd0f57ad11")]
[assembly: AssemblyProduct("MultitudesNoPriceScale")]
[assembly: AssemblyTitle("MultitudesNoPriceScale")]
[assembly: AssemblyVersion("1.1.1.0")]
namespace SnoresvilleMultitudes;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.Snoresville.MultitudesNoPriceScale", "Multitudes No Price Scale", "1.1.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class MultitudesNoPriceScale : BaseUnityPlugin
{
	private bool monstersLogged;

	private const string HalcyonShrineTypeName = "RoR2.HalcyoniteShrineInteractable";

	private const string QuantityIncreaseFieldName = "quantityIncreaseFromBuyIn";

	private static FieldInfo quantityIncreaseFromBuyIn;

	public const string GUID = "com.Snoresville.MultitudesNoPriceScale";

	public const string NAME = "Multitudes No Price Scale";

	public const string MODVERSION = "1.1.1";

	private bool inSpawn;

	private const float DuplicateMinRadius = 3f;

	private const float DuplicateMaxRadius = 14f;

	private const string CloneSuffix = "(Clone)";

	private readonly HashSet<string> bannedCache = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	private readonly HashSet<string> alwaysBannedCache = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	public static ConfigEntry<float> ConfigInteractableScaling { get; set; }

	public static ConfigEntry<int> ConfigMonsterScaling { get; set; }

	public static ConfigEntry<bool> ConfigLiftMonsterLimit { get; set; }

	public static ConfigEntry<float> ConfigPlayerInteractableScaling { get; set; }

	public static ConfigEntry<float> ConfigPlayerMonsterScaling { get; set; }

	public static ConfigEntry<bool> ConfigBanMonsters { get; set; }

	public static ConfigEntry<string> ConfigBannedMonsters { get; set; }

	public static ConfigEntry<string> ConfigAlwaysBannedMonsters { get; set; }

	public static ConfigEntry<bool> ConfigMultiplyBossRewards { get; set; }

	public static ConfigEntry<bool> ConfigMultiplyHalcyonRewards { get; set; }

	public static ConfigEntry<bool> ConfigListMonsters { get; set; }

	public static ConfigEntry<bool> ConfigLogEverySpawn { get; set; }

	public static ConfigEntry<bool> ConfigLogRoutineBails { get; set; }

	public static ConfigEntry<bool> ConfigLogBans { get; set; }

	public static ConfigEntry<bool> ConfigLogDuplications { get; set; }

	public static ConfigEntry<bool> ConfigLogShortfalls { get; set; }

	private void HookMonsterListing()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		MainMenuController.Start += (hook_Start)delegate(orig_Start orig, MainMenuController self)
		{
			orig.Invoke(self);
			SafeLogCharacterBodies();
		};
		Run.onRunStartGlobal += delegate
		{
			SafeLogCharacterBodies();
		};
	}

	private void SafeLogCharacterBodies()
	{
		if (!ConfigListMonsters.Value || monstersLogged)
		{
			return;
		}
		monstersLogged = true;
		try
		{
			LogCharacterBodies();
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Could not list monsters: {arg}");
		}
	}

	private string GetBodyDisplayName(CharacterBody body)
	{
		try
		{
			if (!string.IsNullOrEmpty(body.baseNameToken))
			{
				string text = Language.GetString(body.baseNameToken);
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
			}
		}
		catch (Exception)
		{
		}
		return ((Object)body).name;
	}

	private void LogCharacterBodies()
	{
		((BaseUnityPlugin)this).Logger.LogMessage((object)"----- Multitudes No Price Scale 1.1.1: character bodies -----");
		List<CharacterBody> list = new List<CharacterBody>();
		foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
		{
			if ((Object)(object)allBodyPrefabBodyBodyComponent != (Object)null)
			{
				list.Add(allBodyPrefabBodyBodyComponent);
			}
		}
		list.Sort((CharacterBody a, CharacterBody b) => string.Compare(GetBodyDisplayName(a), GetBodyDisplayName(b), StringComparison.Ordinal));
		foreach (CharacterBody item in list)
		{
			((BaseUnityPlugin)this).Logger.LogMessage((object)(GetBodyDisplayName(item) + " = " + ((Object)((Component)item).gameObject).name));
		}
		((BaseUnityPlugin)this).Logger.LogMessage((object)string.Format("----- {0} {1}: {2} bodies -----", "Multitudes No Price Scale", "1.1.1", list.Count));
	}

	private void HookHalcyonShrine()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		Type type = FindType("RoR2.HalcyoniteShrineInteractable");
		if (type == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"RoR2.HalcyoniteShrineInteractable not found. Halcyon shrine rewards will not be multiplied.");
			return;
		}
		quantityIncreaseFromBuyIn = AccessTools.Field(type, "quantityIncreaseFromBuyIn");
		if (quantityIncreaseFromBuyIn == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find quantityIncreaseFromBuyIn. Halcyon shrine rewards will not be multiplied.");
			return;
		}
		HalcyoniteShrineInteractable.DropRewards += (hook_DropRewards)delegate(orig_DropRewards orig, HalcyoniteShrineInteractable self)
		{
			if (ConfigMultiplyHalcyonRewards.Value && NetworkServer.active)
			{
				try
				{
					int num = (int)quantityIncreaseFromBuyIn.GetValue(self);
					quantityIncreaseFromBuyIn.SetValue(self, num * GetMonsterScale());
				}
				catch (Exception arg)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)$"Could not multiply the Halcyon shrine reward: {arg}");
				}
			}
			orig.Invoke(self);
		};
		((BaseUnityPlugin)this).Logger.LogMessage((object)"Halcyon shrine rewards can be multiplied by the monster count, see Reward Scaling Settings.");
	}

	private static Type FindType(string name)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = assemblies[i].GetType(name);
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}

	public void Awake()
	{
		BindScalingConfig();
		BindBanConfig();
		BindDebugConfig();
		RebuildBanCache();
		RebuildAlwaysBannedCache();
		HookInteractableScaling();
		HookMonsterDuplication();
		HookBossRewards();
		HookMonsterListing();
		TryHookHalcyonShrine();
		SetupOptionsMenu();
		TryApplyTeamLimitPatch();
	}

	private void TryHookHalcyonShrine()
	{
		try
		{
			HookHalcyonShrine();
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Could not hook the Halcyon shrine. Its rewards will not be multiplied: {arg}");
		}
	}

	private void TryApplyTeamLimitPatch()
	{
		try
		{
			TeamLimitPatch.Apply(((BaseUnityPlugin)this).Logger);
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Could not apply the team limit patch. The 40 monster limit will still apply: {arg}");
		}
	}

	private void BindScalingConfig()
	{
		ConfigInteractableScaling = ((BaseUnityPlugin)this).Config.Bind<float>("Normal Scaling Settings", "Interactable Scaling", 4f, "Multiplies the spawn count of interactables.");
		ConfigMonsterScaling = ((BaseUnityPlugin)this).Config.Bind<int>("Normal Scaling Settings", "Monster Scaling", 4, "Multiplies the spawn count of monsters.");
		ConfigLiftMonsterLimit = ((BaseUnityPlugin)this).Config.Bind<bool>("Normal Scaling Settings", "Lift Monster Limit", true, "Lifts the game's 40 monster limit, which also lets shrines keep spawning.");
		ConfigPlayerInteractableScaling = ((BaseUnityPlugin)this).Config.Bind<float>("Player Scaling Settings", "Player Interactable Scaling", 0f, "Multiplies this with the player count before multiplying the interactable multiplier. Set to zero to not scale this by player count.");
		ConfigPlayerMonsterScaling = ((BaseUnityPlugin)this).Config.Bind<float>("Player Scaling Settings", "Player Monster Scaling", 0f, "Multiplies this with the player count before multiplying the monster multiplier. Set to zero to not scale this by player count.");
	}

	private void BindBanConfig()
	{
		ConfigBanMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("Ban Settings", "Ban Monsters", false, "Stop duplicating the monsters listed below.");
		ConfigBannedMonsters = ((BaseUnityPlugin)this).Config.Bind<string>("Ban Settings", "Banned Monsters", "BrotherBody, ScavLunar1Body, VoidRaidCrabBody, FalseSonBossBody, SolusHeartBody, ProvBody", "Comma-separated list of monster names. Must be internal names. (Default: Mithrix, Lunar Scavenger, Voidling, False Son, Solus Heart, Providence)");
		ConfigListMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("Ban Settings", "List Monsters", false, "Prints every monster and its internal name to the console when the game starts, so you can find names to put in the list above.");
		ConfigAlwaysBannedMonsters = ((BaseUnityPlugin)this).Config.Bind<string>("Ban Settings", "Always Banned Monsters", "KarmaSpireBody", "Comma-separated list that is never duplicated, whether or not Ban Monsters is on. (Default: the Mithrix karma spire)");
		ConfigMultiplyBossRewards = ((BaseUnityPlugin)this).Config.Bind<bool>("Reward Scaling Settings", "Multiply Boss Rewards", true, "Drops boss rewards once per monster multiple.");
		ConfigMultiplyHalcyonRewards = ((BaseUnityPlugin)this).Config.Bind<bool>("Reward Scaling Settings", "Multiply Halcyon Shrine Rewards", true, "Gives Halcyon shrine rewards once per monster multiple.");
		ConfigBannedMonsters.SettingChanged += OnBannedMonstersChanged;
		ConfigAlwaysBannedMonsters.SettingChanged += OnAlwaysBannedMonstersChanged;
	}

	private void BindDebugConfig()
	{
		ConfigLogEverySpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug Settings", "Log Every Spawn", false, "Logs a line for every character the director tries to spawn. Very noisy.");
		ConfigLogRoutineBails = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug Settings", "Log Routine Bails", false, "Logs when a spawn is skipped for an everyday reason, such as being one of our own duplicates.");
		ConfigLogBans = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug Settings", "Log Bans", false, "Logs when a spawn is skipped because it is on the player team or on the ban list.");
		ConfigLogDuplications = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug Settings", "Log Duplications", true, "Logs each time a group of monsters is multiplied.");
		ConfigLogShortfalls = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug Settings", "Log Shortfalls", true, "Logs when a group could not be multiplied all the way.");
	}

	public float GetInteractableScale()
	{
		float num = ConfigInteractableScaling.Value;
		if (ConfigPlayerInteractableScaling.Value > 0f)
		{
			num *= (float)Run.instance.participatingPlayerCount * ConfigPlayerInteractableScaling.Value;
		}
		return num;
	}

	public int GetMonsterScale()
	{
		float num = ConfigMonsterScaling.Value;
		if (ConfigPlayerMonsterScaling.Value > 0f)
		{
			num *= (float)Run.instance.participatingPlayerCount * ConfigPlayerMonsterScaling.Value;
		}
		return (int)num;
	}

	private void SetupOptionsMenu()
	{
		if (PluginAvailability.RiskOfOptions)
		{
			ModSettingsManager.SetModDescription("multiply the items and monsters");
			AddOption<float>(ConfigInteractableScaling);
			AddOption<int>(ConfigMonsterScaling);
			AddOption<bool>(ConfigLiftMonsterLimit);
			AddOption<float>(ConfigPlayerInteractableScaling);
			AddOption<float>(ConfigPlayerMonsterScaling);
			AddOption<bool>(ConfigBanMonsters);
			AddOption<string>(ConfigBannedMonsters);
			AddOption<string>(ConfigAlwaysBannedMonsters);
			AddOption<bool>(ConfigMultiplyBossRewards);
			AddOption<bool>(ConfigMultiplyHalcyonRewards);
			AddOption<bool>(ConfigListMonsters);
			AddOption<bool>(ConfigLogEverySpawn);
			AddOption<bool>(ConfigLogRoutineBails);
			AddOption<bool>(ConfigLogBans);
			AddOption<bool>(ConfigLogDuplications);
			AddOption<bool>(ConfigLogShortfalls);
		}
	}

	private static void AddOption<T>(ConfigEntry<T> entry)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		if (!(entry is ConfigEntry<bool> val))
		{
			if (!(entry is ConfigEntry<float> val2))
			{
				if (!(entry is ConfigEntry<int> val3))
				{
					if (entry is ConfigEntry<string> val4)
					{
						ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(val4));
					}
				}
				else
				{
					ModSettingsManager.AddOption((BaseOption)new IntFieldOption(val3));
				}
			}
			else
			{
				ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(val2));
			}
		}
		else
		{
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(val));
		}
	}

	private void HookInteractableScaling()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		SceneDirector.PopulateScene += (hook_PopulateScene)delegate(orig_PopulateScene orig, SceneDirector self)
		{
			if (!NetworkServer.active)
			{
				orig.Invoke(self);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)$"Interactable count increased by {GetInteractableScale()}");
				((BaseUnityPlugin)this).Logger.LogDebug((object)$"Monster count increased by {GetMonsterScale()}");
				self.interactableCredit = (int)((float)self.interactableCredit * GetInteractableScale());
				orig.Invoke(self);
			}
		};
	}

	private void HookMonsterDuplication()
	{
		SpawnCard.onSpawnedServerGlobal += SpawnCardOnSpawnedServerGlobal;
	}

	private void HookBossRewards()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		BossGroup.DropRewards += (hook_DropRewards)delegate(orig_DropRewards orig, BossGroup self)
		{
			if (!NetworkServer.active)
			{
				orig.Invoke(self);
			}
			else if (!ConfigMultiplyBossRewards.Value)
			{
				orig.Invoke(self);
			}
			else
			{
				for (int i = 1; i <= GetMonsterScale(); i++)
				{
					orig.Invoke(self);
				}
			}
		};
	}

	private void SpawnCardOnSpawnedServerGlobal(SpawnResult result)
	{
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Invalid comparison between Unknown and I4
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active)
		{
			return;
		}
		string arg = ((result.spawnRequest != null && (Object)(object)result.spawnRequest.spawnCard != (Object)null) ? ((Object)result.spawnRequest.spawnCard).name : "<null>");
		if (ConfigLogEverySpawn.Value)
		{
			((BaseUnityPlugin)this).Logger.LogDebug((object)$"Spawn check: card='{arg}' success={result.success}");
		}
		if (!result.success || !(result.spawnRequest.spawnCard is CharacterSpawnCard))
		{
			return;
		}
		if (inSpawn)
		{
			if (ConfigLogRoutineBails.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)"Spawn check: bailed, this is our own duplicate");
			}
			return;
		}
		if ((Object)(object)result.spawnedInstance == (Object)null)
		{
			if (ConfigLogRoutineBails.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)"Spawn check: bailed, spawned instance is null");
			}
			return;
		}
		string name = ((Object)result.spawnedInstance).name;
		CharacterMaster component = result.spawnedInstance.GetComponent<CharacterMaster>();
		if ((Object)(object)component == (Object)null)
		{
			if (ConfigLogRoutineBails.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + name + "' has no CharacterMaster"));
			}
			return;
		}
		CharacterBody val = default(CharacterBody);
		if (!component.TryGetBody(ref val) || (Object)(object)val == (Object)null)
		{
			if (ConfigLogRoutineBails.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + name + "' body is not resolved yet"));
			}
			return;
		}
		string name2 = ((Object)((Component)val).gameObject).name;
		TeamComponent component2 = ((Component)val).GetComponent<TeamComponent>();
		if ((Object)(object)component2 == (Object)null)
		{
			if (ConfigLogRoutineBails.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + name2 + "' has no TeamComponent"));
			}
		}
		else if ((int)component2.teamIndex == 1)
		{
			if (ConfigLogBans.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + name2 + "' is on the player team"));
			}
		}
		else
		{
			if (IsBanned(name2))
			{
				return;
			}
			int monsterScale = GetMonsterScale();
			int num = 1;
			int count = TeamComponent.GetTeamMembers((TeamIndex)2).Count;
			if (ConfigLogDuplications.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)$"Spawn check: duplicating '{name2}' to {monsterScale}, monster team holds {count}");
			}
			Vector3 position = ((Component)val).gameObject.transform.position;
			bool ignoreTeamMemberLimit = result.spawnRequest.ignoreTeamMemberLimit;
			result.spawnRequest.ignoreTeamMemberLimit = true;
			try
			{
				for (int i = 1; i < monsterScale; i++)
				{
					inSpawn = true;
					GameObject val2 = null;
					try
					{
						val2 = SpawnDuplicate(result.spawnRequest.spawnCard, result.spawnRequest, position);
					}
					catch (Exception ex)
					{
						Debug.LogError((object)"Something has gone wrong");
						Debug.LogError((object)ex.ToString());
					}
					finally
					{
						inSpawn = false;
					}
					if ((Object)(object)val2 != (Object)null)
					{
						num++;
					}
				}
			}
			finally
			{
				result.spawnRequest.ignoreTeamMemberLimit = ignoreTeamMemberLimit;
			}
			if (num != monsterScale && ConfigLogShortfalls.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)$"Spawn check: '{name2}' only reached {num} of {monsterScale}; card={((Object)result.spawnRequest.spawnCard).name}");
			}
		}
	}

	private GameObject SpawnDuplicate(SpawnCard card, DirectorSpawnRequest request, Vector3 origin)
	{
		//IL_0026: 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)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		float num = Random.Range(0f, 360f) * (MathF.PI / 180f);
		float num2 = Random.Range(3f, 14f);
		Vector3 val = origin + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * num2;
		Quaternion val2 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
		return card.DoSpawn(val, val2, request).spawnedInstance;
	}

	private void OnBannedMonstersChanged(object sender, EventArgs args)
	{
		RebuildBanCache();
	}

	private void OnAlwaysBannedMonstersChanged(object sender, EventArgs args)
	{
		RebuildAlwaysBannedCache();
	}

	private void RebuildAlwaysBannedCache()
	{
		alwaysBannedCache.Clear();
		string[] array = ConfigAlwaysBannedMonsters.Value.Split(',');
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (text.Length > 0)
			{
				alwaysBannedCache.Add(text);
			}
		}
	}

	private void RebuildBanCache()
	{
		bannedCache.Clear();
		string[] array = ConfigBannedMonsters.Value.Split(',');
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (text.Length > 0)
			{
				bannedCache.Add(text);
			}
		}
	}

	private bool IsBanned(string spawnedName)
	{
		if (!ConfigBanMonsters.Value && alwaysBannedCache.Count == 0)
		{
			return false;
		}
		string text = spawnedName;
		if (text.EndsWith("(Clone)", StringComparison.Ordinal))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length);
		}
		text = text.Trim();
		if (alwaysBannedCache.Contains(text))
		{
			if (ConfigLogBans.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + text + "' is always banned"));
			}
			return true;
		}
		if (!ConfigBanMonsters.Value)
		{
			return false;
		}
		bool num = bannedCache.Contains(text);
		if (num && ConfigLogBans.Value)
		{
			((BaseUnityPlugin)this).Logger.LogDebug((object)("Spawn check: bailed, '" + text + "' is banned"));
		}
		return num;
	}
}
internal static class PluginAvailability
{
	public static bool RiskOfOptions => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
}
internal static class TeamLimitPatch
{
	private const string MasterSummonTypeName = "RoR2.MasterSummon";

	private const string PerformMethodName = "Perform";

	private const string IgnoreTeamMemberLimitFieldName = "ignoreTeamMemberLimit";

	private const string PluginId = "com.Snoresville.MultitudesNoPriceScale";

	private static FieldInfo ignoreTeamMemberLimit;

	internal static void Apply(ManualLogSource logger)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		if (!MultitudesNoPriceScale.ConfigLiftMonsterLimit.Value)
		{
			logger.LogMessage((object)"The 40 monster limit is left in place. See Normal Scaling Settings.");
			return;
		}
		Type type = FindType("RoR2.MasterSummon");
		if (type == null)
		{
			logger.LogWarning((object)"RoR2.MasterSummon not found.");
			return;
		}
		MethodInfo method = type.GetMethod("Perform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
		ignoreTeamMemberLimit = AccessTools.Field(type, "ignoreTeamMemberLimit");
		if (method == null || ignoreTeamMemberLimit == null)
		{
			logger.LogWarning((object)"Could not patch RoR2.MasterSummon.Perform.");
			return;
		}
		MethodInfo method2 = typeof(TeamLimitPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic);
		if (method2 == null)
		{
			logger.LogWarning((object)"Could not find the team limit prefix.");
			return;
		}
		new Harmony("com.Snoresville.MultitudesNoPriceScale").Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		logger.LogMessage((object)"Patched the soft team member limit.");
	}

	private static void Prefix(object __instance)
	{
		if (NetworkServer.active)
		{
			ignoreTeamMemberLimit?.SetValue(__instance, true);
		}
	}

	private static Type FindType(string name)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = assemblies[i].GetType(name);
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}
}