Decompiled source of MultitudesDifficulty v0.5.1

MultitudesDifficulty.dll

Decompiled 7 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using EntityStates.Croco;
using HarmonyLib;
using MultitudesDifficulty.Properties;
using R2API;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.1.0")]
namespace Local.Difficulty.Multitudes
{
	public static class Session
	{
		public static decimal additionalPlayers;

		public static decimal interactableScale;

		public static bool extraRewards;

		public static decimal incomePenalty;

		public static decimal bonusHealth;

		public static decimal teleporterChargeRate;

		private static Harmony instance = null;

		private static bool broadcast = false;

		private static readonly MethodInfo getPlayerCount = typeof(Run).GetProperty("participatingPlayerCount").GetMethod;

		public static void Begin(Run thisRun)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (instance == null && NetworkServer.active && (Setup.forceEnable || thisRun.selectedDifficulty == Setup.index))
			{
				instance = Harmony.CreateAndPatchAll(typeof(Session), (string)null);
				instance.PatchAll(typeof(Settings));
				SceneDirector.onPrePopulateSceneServer += AdjustInteractableCredits;
				BossGroup.onBossGroupStartServer += AdjustBossRewards;
			}
		}

		public static void End(object _)
		{
			SceneDirector.onPrePopulateSceneServer -= AdjustInteractableCredits;
			BossGroup.onBossGroupStartServer -= AdjustBossRewards;
			broadcast = false;
			Harmony obj = instance;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			instance = null;
		}

		[HarmonyPatch(typeof(SurvivorPodController), "OnPassengerExit")]
		[HarmonyPatch(typeof(WakeUp), "OnExit")]
		[HarmonyPatch(typeof(InfiniteTowerRun), "OnSafeWardActivated")]
		[HarmonyPostfix]
		private static void GreetUser()
		{
			//IL_0045: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			if (broadcast)
			{
				return;
			}
			broadcast = true;
			string text;
			if (Setup.forceEnable || RoR2Application.isInMultiPlayer)
			{
				text = Settings.BuildDescription(verbose: false);
			}
			else
			{
				if (!Setup.eclipseMode)
				{
					return;
				}
				text = "Good luck.";
			}
			text = "<color=#" + ColorUtility.ToHtmlStringRGB(Setup.theme) + ">" + text + "</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = text
			});
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static int AdjustPlayerCount(int playerCount)
		{
			if (playerCount <= 0)
			{
				return playerCount;
			}
			return playerCount + (int)additionalPlayers;
		}

		private static void AdjustInteractableCredits(SceneDirector __instance)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Invalid comparison between Unknown and I4
			ClassicStageInfo val = ClassicStageInfo.instance;
			int valueOrDefault = (val?.bonusInteractibleCreditObjects?.Where(delegate(BonusInteractibleCreditObject obj)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				GameObject objectThatGrantsPointsIfEnabled = obj.objectThatGrantsPointsIfEnabled;
				return ((objectThatGrantsPointsIfEnabled != null) ? new bool?(objectThatGrantsPointsIfEnabled.activeSelf) : null) ?? false;
			}).Sum((BonusInteractibleCreditObject obj) => obj.points)).GetValueOrDefault();
			decimal num = (decimal)(__instance.interactableCredit - valueOrDefault) * Math.Floor(additionalPlayers) / (decimal)(Run.instance.participatingPlayerCount + 1);
			SceneInfo obj2 = SceneInfo.instance;
			SceneDef val2 = ((obj2 != null) ? obj2.sceneDef : null);
			string text = ((val2 != null) ? val2.baseSceneName : null);
			if ((text == "arena" || text == "voidstage" || (val2 != null && (int)val2.sceneType == 2)) && !extraRewards)
			{
				Console.WriteLine("Prevent extra items in hidden realms.");
			}
			else
			{
				num *= 1m - interactableScale;
				decimal num2 = num;
				decimal value = interactableScale * (additionalPlayers % 1m) / 2m;
				decimal? num3 = val?.sceneDirectorInteractibleCredits;
				num = num2 - ((decimal?)value * num3).GetValueOrDefault();
			}
			num = Math.Round(num, MidpointRounding.AwayFromZero);
			__instance.interactableCredit -= (int)num;
			Console.WriteLine($"...removed {num} credits.");
			Run.instance.RecalculateDifficultyCoefficent();
		}

		private static void AdjustBossRewards(BossGroup __instance)
		{
			if (!extraRewards)
			{
				Setup.GetPlayerCount(out var __result);
				int num = (1 + __instance.bonusRewardCount) * AdjustPlayerCount(__result);
				__instance.scaleRewardsByPlayerCount = false;
				__instance.bonusRewardCount *= __result;
				__instance.bonusRewardCount += __result - 1;
				num -= 1 + __instance.bonusRewardCount;
				Console.WriteLine($"Adjusted boss event to drop {num} less item(s).");
			}
		}

		[HarmonyPatch(typeof(TeamManager), "GiveTeamMoney")]
		[HarmonyPrefix]
		private static void AdjustPlayerIncome(ref uint money)
		{
			decimal num = (decimal)money * additionalPlayers;
			num /= (decimal)Run.instance.participatingPlayerCount + additionalPlayers % 1m;
			money -= (uint)(incomePenalty * num);
		}

		[HarmonyPatch(typeof(CombatDirector), "Spawn")]
		[HarmonyPatch(typeof(ScriptedCombatEncounter), "Spawn")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InsertHook(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructionList)
		{
			MethodInfo directorSpawn = typeof(DirectorCore).GetMethod("TrySpawnObject");
			foreach (CodeInstruction instruction in instructionList)
			{
				if (CodeInstructionExtensions.Calls(instruction, directorSpawn) && bonusHealth > 0m)
				{
					yield return new CodeInstruction(OpCodes.Dup, (object)null);
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					if (typeof(CombatDirector) == __originalMethod.DeclaringType)
					{
						yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null);
					}
					else
					{
						yield return new CodeInstruction(OpCodes.Ldnull, (object)null);
					}
					yield return CodeInstruction.Call(typeof(Session), "AddBonusHealth", (Type[])null, (Type[])null);
				}
				yield return instruction;
			}
		}

		private static void AddBonusHealth(DirectorSpawnRequest request, object instance, EliteDef elite)
		{
			request.onSpawnedServer = (Action<SpawnResult>)Delegate.Combine(request.onSpawnedServer, (Action<SpawnResult>)delegate(SpawnResult result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				if (result.success && Object.op_Implicit((Object)(object)result.spawnedInstance))
				{
					double num = 0.0;
					double num2 = (double)additionalPlayers;
					object obj = instance;
					CombatDirector val = (CombatDirector)((obj is CombatDirector) ? obj : null);
					if (val != null && Object.op_Implicit((Object)(object)val.combatSquad) && val.combatSquad.grantBonusHealthInMultiplayer)
					{
						num = (Object.op_Implicit((Object)(object)elite) ? elite.healthBoostCoefficient : 1f);
						num *= num2;
					}
					else
					{
						object obj2 = instance;
						ScriptedCombatEncounter val2 = (ScriptedCombatEncounter)((obj2 is ScriptedCombatEncounter) ? obj2 : null);
						if (val2 == null || !val2.grantUniqueBonusScaling)
						{
							return;
						}
						num = Run.instance.difficultyCoefficient * 2f / 5f;
						num *= Math.Sqrt((double)Run.instance.livingPlayerCount + num2) - Math.Sqrt(Run.instance.livingPlayerCount);
					}
					num *= (double)bonusHealth;
					Console.WriteLine("Applying " + num.ToString("0.#%") + " additional bonus health to '" + ((Object)result.spawnedInstance).name + "'...");
					num = Math.Round(num / 0.1, MidpointRounding.AwayFromZero);
					Inventory component = result.spawnedInstance.GetComponent<Inventory>();
					if (component != null)
					{
						component.GiveItem(Items.BoostHp, (int)num);
					}
				}
			});
		}

		[HarmonyPatch(typeof(HoldoutZoneController), "OnEnable")]
		[HarmonyPrefix]
		private static void AdjustChargeRate(HoldoutZoneController __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			if ((int)__instance.chargingTeam == 1 && __instance.playerCountScaling != 0f)
			{
				Setup.GetPlayerCount(out var __result);
				decimal multiplier = (decimal)__result / ((decimal)__result + teleporterChargeRate * additionalPlayers);
				__instance.calcChargeRate += (CalcChargeRateDelegate)delegate(ref float chargeRate)
				{
					chargeRate *= (float)multiplier;
				};
				Console.WriteLine("Charge rate reduced by " + Settings.FormatPercent(1m - multiplier) + " for holdout zone.");
			}
		}

		[HarmonyPatch(typeof(EscapeSequenceController), "BeginEscapeSequence")]
		[HarmonyPrefix]
		private static void IncreaseCountdown(EscapeSequenceController __instance)
		{
			__instance.countdownDuration *= (float)(1m + teleporterChargeRate * additionalPlayers);
		}

		[HarmonyPatch(typeof(Run), "RecalculateDifficultyCoefficentInternal")]
		[HarmonyPatch(typeof(DirectorMoneyWave), "Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> IncreaseDifficultyCoefficient(IEnumerable<CodeInstruction> instructionList)
		{
			CodeInstruction val = null;
			foreach (CodeInstruction instruction in instructionList)
			{
				if (instruction.opcode == OpCodes.Conv_R4 && CodeInstructionExtensions.Calls(val, getPlayerCount))
				{
					yield return Transpilers.EmitDelegate<Func<int, float>>((Func<int, float>)((int playerCount) => (float)((decimal)playerCount + additionalPlayers % 1m)));
				}
				else
				{
					yield return instruction;
				}
				val = instruction;
			}
		}

		[HarmonyPatch(typeof(ArenaMissionController), "EndRound")]
		[HarmonyPatch(typeof(InfiniteTowerWaveController), "DropRewards")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> IgnorePlayerAdjustment(IEnumerable<CodeInstruction> instructionList)
		{
			foreach (CodeInstruction instruction in instructionList)
			{
				yield return instruction;
				if (!CodeInstructionExtensions.Calls(instruction, getPlayerCount))
				{
					continue;
				}
				yield return Transpilers.EmitDelegate<Func<int, int>>((Func<int, int>)delegate(int playerCount)
				{
					if (!extraRewards)
					{
						Setup.GetPlayerCount(out playerCount);
					}
					return playerCount;
				});
			}
		}
	}
	public static class Settings
	{
		public static void Load(ConfigFile configuration)
		{
			Load(configuration, out var _);
		}

		public static void Load(ConfigFile configuration, out bool eclipse)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			AcceptableValueRange<decimal> val = new AcceptableValueRange<decimal>(0m, 100m);
			int order = 0;
			try
			{
				configuration.Reload();
			}
			catch (FileNotFoundException)
			{
				configuration.Clear();
			}
			string title = default(string);
			section("General");
			Session.additionalPlayers = configuration.Bind<decimal>(title, "Additional Player Count", 1m, new ConfigDescription("Add this many players to the game, increasing the difficulty of enemies. Also affects the other options listed below.", (AcceptableValueBase)(object)new AcceptableValueRange<decimal>(0.25m, 250m), Array.Empty<object>())).Value;
			eclipse = configuration.Bind<bool>(title, "Eclipse Mode", false, "Use eclipse modifiers. Please note, this requires a restart in order to take effect.").Value;
			section("Advanced");
			Session.interactableScale = configuration.Bind<decimal>(title, "Additional Interactables", 0m, new ConfigDescription("Increase this percentage for more loot (i.e. chests, shrines, etc.) on each stage, proportional to player count.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue;
			Session.extraRewards = configuration.Bind<bool>(title, "Extra Item Rewards", false, "Enable to drop additional items from the teleporter event, other bosses, and hidden realms.").Value;
			Session.incomePenalty = configuration.Bind<decimal>(title, "Income Penalty", 75m, new ConfigDescription("Gold is typically split between all players. Lower this value to lessen this effect, increasing player income.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue;
			Session.bonusHealth = configuration.Bind<decimal>(title, "Bonus Health", 0m, new ConfigDescription("Certain enemies receive bonus health in multiplayer. Reduce the amount granted to teleporter bosses and unique encounters.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue;
			Session.teleporterChargeRate = configuration.Bind<decimal>(title, "Teleporter Duration", 0m, new ConfigDescription("The extent at which player count is considered when determining charge rate for holdout zones. Not recommended.", (AcceptableValueBase)(object)val, Array.Empty<object>())).Value / val.MaxValue;
			section("Other");
			Setup.lobbyPlayerCount = !configuration.Bind<bool>(title, "Ignore Disconnected Players", false, "By default, players that leave a multiplayer lobby are still taken into account, until they reconnect.").Value;
			Setup.forceEnable = configuration.Bind<bool>(title, "Force Enable", false, "For use with other difficulty options. Apply the increase to player count regardless of selection.").Value;
			void section(string name)
			{
				int num = ++order;
				title = num + ". " + name;
			}
		}

		[HarmonyPatch(typeof(CurrentDifficultyIconController), "Start")]
		[HarmonyPrefix]
		private static void ShowPlayerCount(Component __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = __instance.transform;
			HGTextMeshProUGUI obj = new GameObject("PlayerText").AddComponent<HGTextMeshProUGUI>();
			Transform transform2 = ((TMP_Text)obj).transform;
			transform2.SetParent(transform);
			transform2.localPosition = Vector3.zero;
			transform2.localRotation = new Quaternion(0f, (0f - transform.rotation.y) * 0.25f, 0f, 1f);
			transform2.localScale = Vector3.one;
			RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
			rectTransform.anchorMin = Vector2.right;
			rectTransform.anchorMax = Vector2.one + Vector2.right * 1.5f;
			rectTransform.offsetMin = Vector2.down - Vector2.one * 0.75f;
			rectTransform.offsetMax = Vector2.zero;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)1025;
			((TMP_Text)obj).fontSize = 12f;
			((TMP_Text)obj).faceColor = Color32.op_Implicit(Setup.theme);
			((TMP_Text)obj).outlineWidth = 0.125f;
			Run instance = Run.instance;
			int num = ((instance != null) ? instance.participatingPlayerCount : 0);
			((TMP_Text)obj).SetText(FormatFraction(Session.additionalPlayers % 1m + (decimal)num) + "P", true);
		}

		public static string BuildDescription(bool verbose = true)
		{
			string text = "";
			if (verbose)
			{
				text = "For those who wish to face vast hordes of enemies alone. Multiplayer difficulty levels are in effect.\n\n<style=cStack>>Base Difficulty:</style> <style=cSub>" + (Setup.eclipseMode ? "Eclipse" : "Monsoon") + "</style>\n";
			}
			string colorHexString = ColorCatalog.GetColorHexString((ColorIndex)4);
			string colorHexString2 = ColorCatalog.GetColorHexString((ColorIndex)5);
			return text + "<style=cStack>>Player Count:</style> <style=cDeath>+" + FormatFraction(Session.additionalPlayers) + "</style>\n<style=cStack>>Additional Interactables:</style> <style=cShrine>" + FormatPercent(Session.interactableScale, "None") + "</style>\n<style=cStack>>Extra Item Rewards:</style> " + (Session.extraRewards ? "<style=cIsHealing>Enabled</style>\n" : ("<color=#" + colorHexString2 + ">Disabled</color>\n")) + "<style=cStack>>Player Income:</style> <style=cIsUtility>+" + FormatPercent(1m - Session.incomePenalty) + " </style>\n<style=cStack>>Enemy Bonus Health:</style> <style=cIsVoid>" + FormatPercent(Session.bonusHealth - 1m, "+100%", "Off") + "</style>\n<style=cStack>>Teleporter Duration:</style> <sprite name=\"TP\"><color=#" + colorHexString + ">+" + FormatPercent(Session.teleporterChargeRate) + "</color>";
		}

		private static string FormatFraction(decimal value)
		{
			decimal num = Math.Truncate(value);
			string text = "";
			decimal num2 = value - num;
			if (!(num2 < 0.375m))
			{
				text = ((!(num2 > 0.625m)) ? "½" : "¾");
			}
			else if (num2 == 0m)
			{
				if (num == 0m)
				{
					return "0";
				}
			}
			else
			{
				text = "¼";
			}
			if (!(num != 0m))
			{
				return text;
			}
			return num + text;
		}

		public static string FormatPercent(decimal value, string zero = null, string one = null)
		{
			string text = null;
			if (value == -1m)
			{
				goto IL_002f;
			}
			if (!(value == 0m))
			{
				if (value == 1m)
				{
					goto IL_002f;
				}
			}
			else
			{
				text = zero;
			}
			goto IL_0031;
			IL_0031:
			return text ?? value.ToString("0.#%");
			IL_002f:
			text = one;
			goto IL_0031;
		}
	}
	[BepInPlugin("local.difficulty.multitudes", "MultitudesDifficulty", "0.5.1")]
	public class Setup : BaseUnityPlugin
	{
		public const string identifier = "local.difficulty.multitudes";

		public const string version = "0.5.1";

		public static DifficultyIndex index;

		public static Color theme;

		private static DifficultyDef difficulty;

		private static RuleChoiceDef other;

		private static RuleChoiceDef choice;

		public static bool eclipseMode;

		public static bool lobbyPlayerCount;

		public static bool forceEnable;

		public void Awake()
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Settings.Load(((BaseUnityPlugin)this).Config, out eclipseMode);
			SceneManager.sceneUnloaded += delegate
			{
				Settings.Load(((BaseUnityPlugin)this).Config);
				choice.tooltipBodyToken = (difficulty.descriptionToken = Settings.BuildDescription());
				choice.excludeByDefault = forceEnable;
			};
			Color val = Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)15));
			theme = new Color(val.r, val.b, val.g);
			index = (DifficultyIndex)(eclipseMode ? 127 : (-128));
			difficulty = new DifficultyDef(DifficultyCatalog.GetDifficultyDef((DifficultyIndex)2).scalingValue, "Multitudes", (string)null, (string)null, theme, "mod", true);
			Texture2D val2 = new Texture2D(256, 256, (TextureFormat)5, 3, false);
			difficulty.foundIconSprite = ImageConversion.LoadImage(val2, eclipseMode ? Resources.eclipse : Resources.icon);
			difficulty.iconSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), Vector2.zero);
			Harmony.CreateAndPatchAll(typeof(Setup), (string)null);
			Run.onRunStartGlobal += Session.Begin;
			Run.onRunDestroyGlobal += Session.End;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool GetPlayerCount(out int __result)
		{
			ReadOnlyCollection<PlayerCharacterMasterController> instances = PlayerCharacterMasterController.instances;
			__result = (lobbyPlayerCount ? instances.Count : instances.Where((PlayerCharacterMasterController player) => player.isConnected).Count());
			return false;
		}

		[HarmonyPatch(typeof(RuleCatalog), "Init")]
		[HarmonyPostfix]
		private static void AddDifficulty()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Invalid comparison between Unknown and I4
			RuleDef obj = RuleCatalog.allRuleDefs.First();
			choice = obj.AddChoice(difficulty.nameToken, (object)null, false);
			choice.difficultyIndex = index;
			choice.tooltipNameToken = difficulty.nameToken;
			choice.tooltipNameColor = difficulty.color;
			choice.serverTag = difficulty.serverTag;
			choice.sprite = difficulty.iconSprite;
			choice.globalIndex = RuleCatalog.allChoicesDefs.Count;
			RuleCatalog.allChoicesDefs.Add(choice);
			RuleCatalog.ruleChoiceDefsByGlobalName[choice.globalName] = choice;
			foreach (RuleChoiceDef choice in obj.choices)
			{
				if ((int)choice.difficultyIndex == (eclipseMode ? 10 : 2))
				{
					other = choice;
					break;
				}
			}
			CheckCompatibility(Chainloader.PluginInfos);
		}

		private static void CheckCompatibility(Dictionary<string, PluginInfo> info)
		{
			PluginInfo value;
			if (info.ContainsKey("com.bepis.r2api.difficulty"))
			{
				SupportAPI();
			}
			else if (info.TryGetValue("com.bepis.r2api", out value) && value.Metadata.Version <= Version.Parse("4.4.1"))
			{
				LegacySupport();
			}
			[MethodImpl(MethodImplOptions.NoInlining)]
			static void LegacySupport()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (DifficultyAPI.Loaded)
				{
					DifficultyAPI.difficultyDefinitions[index] = difficulty;
				}
			}
			[MethodImpl(MethodImplOptions.NoInlining)]
			static void SupportAPI()
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				DifficultyAPI.difficultyDefinitions[index] = difficulty;
			}
		}

		[HarmonyPatch(typeof(DifficultyCatalog), "GetDifficultyDef")]
		[HarmonyPrefix]
		private static bool GetDifficulty(DifficultyIndex difficultyIndex, ref DifficultyDef __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (difficultyIndex == index)
			{
				__result = difficulty;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(NetworkExtensions), "Write", new Type[]
		{
			typeof(NetworkWriter),
			typeof(RuleBook)
		})]
		[HarmonyPrefix]
		private static void AdjustRuleBook(ref RuleBook src)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (src.FindDifficulty() == index)
			{
				RuleBook val = new RuleBook();
				val.Copy(src);
				val.ApplyChoice(other);
				src = val;
			}
		}

		[HarmonyPatch(typeof(Run), "OnSerialize")]
		[HarmonyPrefix]
		private static void SendBaseIndex(Run __instance, ref int __state)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			__state = __instance.selectedDifficultyInternal;
			if (index == __instance.selectedDifficulty)
			{
				__instance.selectedDifficultyInternal = (int)other.difficultyIndex;
			}
		}

		[HarmonyPatch(typeof(Run), "OnSerialize")]
		[HarmonyPostfix]
		private static void RestoreIndex(Run __instance, int __state)
		{
			__instance.selectedDifficultyInternal = __state;
		}
	}
}
namespace MultitudesDifficulty.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("MultitudesDifficulty.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] eclipse => (byte[])ResourceManager.GetObject("eclipse", resourceCulture);

		internal static byte[] icon => (byte[])ResourceManager.GetObject("icon", resourceCulture);

		internal Resources()
		{
		}
	}
}