Decompiled source of MultitudesDifficulty v1.1.0

MultitudesDifficulty.dll

Decompiled 3 weeks 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.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using EntityStates.AurelioniteHeart;
using EntityStates.Croco;
using EntityStates.FalseSonBoss;
using EntityStates.Geode;
using EntityStates.Missions.GeodeSecretMission;
using EntityStates.VoidCamp;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.Utils;
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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[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 Local.Difficulty.Multitudes
{
	public static class Session
	{
		public static decimal players;

		public static decimal interactableScale;

		public static bool multiply;

		public static bool extraRewards;

		public static decimal incomePenalty;

		public static decimal bonusHealth;

		public static decimal teleporterChargeRate;

		private static Harmony instance;

		private static bool broadcast;

		[Obsolete("If needed, refer to `GetAdditionalPlayers` instead.")]
		public static readonly decimal additionalPlayers;

		internal 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(Settings), (string)null);
				instance.PatchAll(typeof(Session));
			}
		}

		internal static void End(object _)
		{
			broadcast = false;
			Harmony obj = instance;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			instance = null;
		}

		public static decimal GetAdditionalPlayers(decimal limit = 1m)
		{
			Setup.GetPlayerCount(out var __result);
			if (multiply)
			{
				return (decimal)__result * (players - 1m) * limit;
			}
			if (__result > 0)
			{
				return players * limit;
			}
			return 0m;
		}

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

		[HarmonyPatch(typeof(SceneDirector), "Start")]
		[HarmonyILManipulator]
		private static void AdjustInteractableCredits(ILContext context)
		{
			InsertHook(context, typeof(Session).GetField("interactableScale"), typeof(Run).GetProperty("participatingPlayerCount").GetMethod);
		}

		[HarmonyPatch(typeof(BossGroup), "DropRewards")]
		[HarmonyILManipulator]
		private static void AdjustBossRewards(ILContext context)
		{
			ApplyPlayerAdjustment(context);
		}

		[HarmonyPatch(typeof(TeamManager), "GiveTeamMoney", new Type[]
		{
			typeof(TeamIndex),
			typeof(uint)
		})]
		[HarmonyILManipulator]
		private static void AdjustPlayerIncome(ILContext context)
		{
			InsertHook(context, typeof(Session).GetField("incomePenalty"), typeof(Run).GetProperty("livingPlayerCount").GetMethod);
		}

		internal static void InsertHook(ILContext context, FieldInfo field, MethodInfo method)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(context);
			string fullName = ((MemberReference)context.Method).FullName;
			while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, (MethodBase)method)
			}))
			{
				int index = int.MinValue;
				while (OpCodes.Conv_R4 != val.Next.OpCode)
				{
					if (index < 0)
					{
						val.TryGotoNext(new Func<Instruction, bool>[1]
						{
							(Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref index)
						});
					}
					if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, index)
					}))
					{
						Console.WriteLine("Unable to insert hook.\n\t" + fullName);
						return;
					}
				}
				int index2 = val.Index + 1;
				val.Index = index2;
				val.Emit(OpCodes.Ldsfld, field);
				val.Emit(OpCodes.Call, (MethodBase)typeof(Session).GetMethod("GetAdditionalPlayers"));
				val.Emit(OpCodes.Call, (MethodBase)typeof(decimal).GetMethod("ToSingle"));
				val.Emit(OpCodes.Add);
			}
			if (val.Index == 0)
			{
				Console.WriteLine("No match found.\n\t" + fullName);
			}
		}

		[HarmonyPatch(typeof(CombatDirector), "Spawn")]
		[HarmonyPatch(typeof(CharacterMaster), "ScaleDifficultyAsBoss")]
		[HarmonyILManipulator]
		private static void AddBonusHealth(ILContext context, MethodBase __originalMethod)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			if (__originalMethod.DeclaringType == typeof(CombatDirector))
			{
				MethodReference target = null;
				MethodReference val = default(MethodReference);
				Func<Instruction, bool>[] array = new Func<Instruction, bool>[3]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdftn(i, ref target),
					(Instruction i) => ILPatternMatchingExt.MatchNewobj(i, ref val),
					(Instruction i) => ILPatternMatchingExt.MatchStfld<DirectorSpawnRequest>(i, "onSpawnedServer")
				};
				if (new ILCursor(context).TryGotoNext(array))
				{
					instance.Patch(ReflectionHelper.ResolveReflection(target), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(MethodBase.GetCurrentMethod() as MethodInfo));
					return;
				}
			}
			InsertHook(context, typeof(Session).GetField("bonusHealth"), typeof(Run).GetProperty("livingPlayerCount").GetMethod);
		}

		[HarmonyPatch(typeof(HoldoutZoneController), "DoUpdate")]
		[HarmonyILManipulator]
		private static void AdjustChargeRate(ILContext context)
		{
			MethodInfo method = typeof(HoldoutZoneController).GetMethod("CountLivingPlayers", AccessTools.all);
			InsertHook(context, typeof(Session).GetField("teleporterChargeRate"), method);
		}

		[HarmonyPatch(typeof(EscapeSequenceController), "BeginEscapeSequence")]
		[HarmonyPrefix]
		private static void IncreaseCountdown(EscapeSequenceController __instance)
		{
			decimal num = GetAdditionalPlayers(teleporterChargeRate);
			Setup.GetPlayerCount(out var __result);
			if (num > 0m)
			{
				__instance.countdownDuration *= decimal.ToSingle(1m + num / (decimal)__result);
			}
		}

		[HarmonyPatch(typeof(Run), "RecalculateDifficultyCoefficentInternal")]
		[HarmonyPatch(typeof(DirectorMoneyWave), "Update")]
		[HarmonyPatch(typeof(OnCollisionEventController), "OnTriggerStay")]
		[HarmonyILManipulator]
		private static void IncreaseDifficultyCoefficient(ILContext context)
		{
			InsertHook(context, typeof(decimal).GetField("One"), typeof(Run).GetProperty("participatingPlayerCount").GetMethod);
		}

		[HarmonyPatch(typeof(ArenaMissionController), "EndRound")]
		[HarmonyPatch(typeof(InfiniteTowerWaveController), "DropRewards")]
		[HarmonyPatch(typeof(Deactivate), "OnEnter")]
		[HarmonyPatch(typeof(HalcyoniteShrineInteractable), "DropRewards")]
		[HarmonyPatch(typeof(SkyJumpDeathState), "GiveColossusItem")]
		[HarmonyPatch(typeof(AurelioniteHeartActivationState), "FixedUpdate")]
		[HarmonyPatch(typeof(GeodeSecretMissionRewardState), "DropRewards")]
		[HarmonyPatch(typeof(GeodeShatter), "OnEnter")]
		[HarmonyPatch(typeof(Death), "OnEnter")]
		[HarmonyILManipulator]
		private static void ApplyPlayerAdjustment(ILContext context)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(context);
			MethodInfo method = typeof(Run).GetProperty("participatingPlayerCount").GetMethod;
			while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, (MethodBase)method)
			}))
			{
				val.Emit(OpCodes.Ldsfld, typeof(decimal).GetField("One"));
				val.Emit(OpCodes.Call, (MethodBase)typeof(Session).GetMethod("GetAdditionalPlayers"));
				val.Emit(OpCodes.Call, (MethodBase)typeof(decimal).GetMethod("ToInt32"));
				val.Emit(OpCodes.Ldsfld, typeof(Session).GetField("extraRewards"));
				val.Emit(OpCodes.Mul);
				val.Emit(OpCodes.Add);
			}
			if (val.Index == 0)
			{
				Console.WriteLine("No match found.\n\t" + ((MemberReference)context.Method).FullName);
			}
		}
	}
	internal static class Settings
	{
		internal static void Load(ConfigFile configuration)
		{
			Load(configuration, out var _);
		}

		internal 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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.players = 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;
			Session.multiply = configuration.Bind<bool>(title, "Use Multiplicative Scaling", false, "Change this in order to multiply player count instead. Similar to the original version.").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;
			Setup.GetPlayerCount(out var __result);
			((TMP_Text)obj).SetText(FormatFraction((decimal)__result + Session.GetAdditionalPlayers()) + "P", true);
		}

		internal 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);
			text = text + "<style=cStack>>Player Count:</style> <style=cDeath>" + (Session.multiply ? "<font-weight=\"900\">×</font-weight>" : "+") + FormatFraction(Session.players) + "</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";
			if (verbose || !(Session.teleporterChargeRate == 0m))
			{
				text = text + "<style=cStack>>Teleporter Duration:</style> <sprite name=\"TP\"><color=#" + colorHexString + ">+" + FormatPercent(Session.teleporterChargeRate) + "</color>";
			}
			return text;
		}

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

		private 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_002f:
			text = one;
			goto IL_0031;
			IL_0031:
			return text ?? value.ToString("0.#%");
		}
	}
	[BepInPlugin("local.difficulty.multitudes", "MultitudesDifficulty", "1.1.0")]
	public class Setup : BaseUnityPlugin
	{
		public const string identifier = "local.difficulty.multitudes";

		public const string version = "1.1.0";

		internal static DifficultyIndex index;

		internal 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;

		protected 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
			{
				if (choice != null)
				{
					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]
		internal 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Invalid comparison between Unknown and I4
			RuleDef obj = RuleCatalog.allRuleDefs.First((RuleDef definition) => definition.globalName == "Difficulty");
			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(NetworkRuleBook), "OnSerialize")]
		[HarmonyPatch(typeof(RunReport), "Write")]
		[HarmonyILManipulator]
		private static void AdjustRuleBook(ILContext context)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			ILCursor val = new ILCursor(context);
			MethodInfo method = typeof(NetworkExtensions).GetMethod("Write", new Type[2]
			{
				typeof(NetworkWriter),
				typeof(RuleBook)
			});
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall(i, (MethodBase)method)
			}))
			{
				val.EmitDelegate<Func<RuleBook, RuleBook>>((Func<RuleBook, RuleBook>)delegate(RuleBook original)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: 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_0027: Expected O, but got Unknown
					if (original.FindDifficulty() == index)
					{
						RuleBook val2 = new RuleBook();
						val2.Copy(original);
						val2.ApplyChoice(other);
						return val2;
					}
					return original;
				});
			}
			else
			{
				Console.WriteLine("Unable to modify rulebook serialization.");
			}
		}

		[HarmonyPatch(typeof(Run), "OnSerialize")]
		[HarmonyILManipulator]
		private static void SendBaseIndex(ILContext context)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			ILCursor val = new ILCursor(context);
			FieldInfo field = typeof(Run).GetField("selectedDifficultyInternal", AccessTools.all);
			while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdfld(i, field)
			}))
			{
				val.EmitDelegate<Func<DifficultyIndex, DifficultyIndex>>((Func<DifficultyIndex, DifficultyIndex>)((DifficultyIndex value) => (value != index) ? value : other.difficultyIndex));
			}
			if (val.Index == 0)
			{
				Console.WriteLine("Unable to map index of difficulty.");
			}
		}
	}
}
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()
		{
		}
	}
}