Decompiled source of Player Limit Mod v2.1.1

PlayerLimitMod.dll

Decompiled 8 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Burst2Flame;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PlayFab.Multiplayer;
using PlayerLimitMod.Patches;
using PlayerLimitMod.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("PlayerLimitMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("PlayerLimitMod")]
[assembly: AssemblyTitle("PlayerLimitMod")]
[assembly: AssemblyVersion("2.0.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 PlayerLimitMod
{
	internal static class Il
	{
		private static readonly MethodInfo MaxPlayersGetter = AccessTools.PropertyGetter(typeof(PlayerLimitPlugin), "MaxPlayers");

		private static readonly HashSet<OpCode> Comparisons = new HashSet<OpCode>
		{
			OpCodes.Cgt,
			OpCodes.Cgt_Un,
			OpCodes.Clt,
			OpCodes.Clt_Un,
			OpCodes.Ceq,
			OpCodes.Blt,
			OpCodes.Blt_S,
			OpCodes.Blt_Un,
			OpCodes.Blt_Un_S,
			OpCodes.Ble,
			OpCodes.Ble_S,
			OpCodes.Ble_Un,
			OpCodes.Ble_Un_S,
			OpCodes.Bgt,
			OpCodes.Bgt_S,
			OpCodes.Bgt_Un,
			OpCodes.Bgt_Un_S,
			OpCodes.Bge,
			OpCodes.Bge_S,
			OpCodes.Bge_Un,
			OpCodes.Bge_Un_S
		};

		public static bool IsSix(CodeInstruction ci)
		{
			if (!(ci.opcode == OpCodes.Ldc_I4_6))
			{
				if (ci.opcode == OpCodes.Ldc_I4_S || ci.opcode == OpCodes.Ldc_I4)
				{
					return Convert.ToInt32(ci.operand) == 6;
				}
				return false;
			}
			return true;
		}

		public static bool FeedsComparison(List<CodeInstruction> code, int i)
		{
			if (i + 1 < code.Count)
			{
				return Comparisons.Contains(code[i + 1].opcode);
			}
			return false;
		}

		public static Func<List<CodeInstruction>, int, bool> FeedsCall(params string[] methodNames)
		{
			return (List<CodeInstruction> code, int i) => i + 1 < code.Count && code[i + 1].operand is MethodInfo methodInfo && methodNames.Contains(methodInfo.Name);
		}

		public static IEnumerable<CodeInstruction> ReplaceSix(IEnumerable<CodeInstruction> instructions, Func<List<CodeInstruction>, int, bool> filter, int expected, string where)
		{
			List<CodeInstruction> list = instructions.ToList();
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (IsSix(list[i]) && filter(list, i))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = MaxPlayersGetter;
					num++;
				}
			}
			if (num != expected)
			{
				PlayerLimitPlugin.Log.LogWarning((object)$"{where}: expected to replace {expected} party-size constant(s) but found {num}. The game may have changed.");
			}
			else
			{
				PlayerLimitPlugin.Debug($"{where}: replaced {num} party-size constant(s)");
			}
			return list;
		}

		public static MethodBase StateMachineMoveNext(Type owner, string sourceMethodName)
		{
			Type type = owner.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((Type t) => t.Name.StartsWith("<" + sourceMethodName + ">", StringComparison.Ordinal));
			if (!(type == null))
			{
				return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
			}
			return null;
		}
	}
	[BepInPlugin("com.stolenrealm.playerlimit", "Player Limit Mod", "2.1.1")]
	public class PlayerLimitPlugin : BaseUnityPlugin
	{
		public const string Guid = "com.stolenrealm.playerlimit";

		public const string Name = "Player Limit Mod";

		public const string Version = "2.1.1";

		public const int VanillaLimit = 6;

		internal static ManualLogSource Log;

		internal static ConfigEntry<int> MaxPlayersEntry;

		internal static ConfigEntry<int> PartySlotsPerPageEntry;

		internal static ConfigEntry<int> PortraitsPerPageEntry;

		internal static ConfigEntry<int> EventPortraitsPerPageEntry;

		internal static ConfigEntry<bool> PortraitFollowSelectionEntry;

		internal static ConfigEntry<bool> ExtraRewardBarsEntry;

		internal static ConfigEntry<bool> VerboseEntry;

		internal static ConfigEntry<float> ExtraEnemyPointsEntry;

		public static int MaxPlayers => Mathf.Clamp(MaxPlayersEntry?.Value ?? 6, 1, 30);

		public static float ExtraEnemyPointsPerHero => Mathf.Clamp(ExtraEnemyPointsEntry?.Value ?? 0f, 0f, 10f);

		public static int PartySlotsPerPage => Mathf.Clamp(PartySlotsPerPageEntry?.Value ?? 6, 1, 12);

		public static int PortraitsPerPage => Mathf.Clamp(PortraitsPerPageEntry?.Value ?? 6, 1, 12);

		public static int EventPortraitsPerPage => Mathf.Clamp(EventPortraitsPerPageEntry?.Value ?? 6, 1, 12);

		internal static void Debug(string msg)
		{
			if (VerboseEntry != null && VerboseEntry.Value)
			{
				Log.LogInfo((object)msg);
			}
		}

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MaxPlayersEntry = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPlayers", 16, new ConfigDescription("Maximum party size (heroes in the party) and lobby size. Vanilla is 6. Everyone in a multiplayer session needs the mod with the same value. Restart the game after changing.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			ExtraEnemyPointsEntry = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "ExtraPointsPerHeroAbove6", 2f, new ConfigDescription("Extra enemy points per hero beyond 6, added when a battle's enemies are rolled (host's setting decides). The game already adds 2 per hero; the default 2 doubles that past 6, keeping about the same enemies-per-hero as a full 6-party. 0 = game's own scaling only. Higher = more enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			PartySlotsPerPageEntry = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PartySlotsPerPage", 6, new ConfigDescription("Party slots shown per page on the character select screen.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>()));
			PortraitsPerPageEntry = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "PortraitsPerPage", 6, new ConfigDescription("Hero portraits shown per page in the left-hand portrait column. Values above 6 may run off small screens.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>()));
			EventPortraitsPerPageEntry = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "EventPortraitsPerPage", 6, new ConfigDescription("Hero tiles shown per page in map events (Choose Character / Choose As Party). The row is sized for 6; higher values may overflow it.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>()));
			PortraitFollowSelectionEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "PortraitsFollowSelection", true, "Automatically flip the portrait column to the page holding the hero you select.");
			ExtraRewardBarsEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ExtraRewardXpBars", true, "Add XP bars on the adventure results screen for heroes beyond the game's 6.");
			VerboseEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Log extra detail to BepInEx/LogOutput.log.");
			Log.LogInfo((object)string.Format("{0} v{1} - game version {2} - MaxPlayers = {3}", "Player Limit Mod", "2.1.1", Application.version, MaxPlayers));
			Harmony val = new Harmony("com.stolenrealm.playerlimit");
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			foreach (Type item in from t in typeof(PlayerLimitPlugin).Assembly.GetTypes()
				where t.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0
				orderby t.Name
				select t)
			{
				try
				{
					List<MethodInfo> list3 = val.CreateClassProcessor(item).Patch();
					if (list3 == null || list3.Count == 0)
					{
						list2.Add(item.Name + " (no target found)");
					}
					else
					{
						list.Add(item.Name);
					}
				}
				catch (Exception ex)
				{
					list2.Add(item.Name);
					Log.LogError((object)("Patch " + item.Name + " failed: " + ex.GetBaseException().Message));
					Debug(ex.ToString());
				}
			}
			Log.LogInfo((object)$"Patches applied: {list.Count}/{list.Count + list2.Count}");
			if (list2.Count > 0)
			{
				Log.LogWarning((object)("Patches NOT applied (the game may have changed): " + string.Join(", ", list2)));
			}
		}
	}
}
namespace PlayerLimitMod.UI
{
	internal static class GoldPager
	{
		private static int _pageSize;

		private static GoldSendManager _mgr;

		private static NavBar _nav;

		private static int _count;

		private static int _page;

		public static void RememberPageSize(int vanillaSlots)
		{
			if (_pageSize == 0)
			{
				_pageSize = vanillaSlots;
			}
		}

		public static void Open(GoldSendManager mgr, int recipients)
		{
			_mgr = mgr;
			_count = recipients;
			_page = 0;
			Apply();
		}

		private static void Step(int delta)
		{
			if (Object.op_Implicit((Object)(object)_mgr))
			{
				int num = Pages();
				int num2 = Mathf.Clamp(_page + delta, 0, num - 1);
				if (num2 != _page)
				{
					_page = num2;
					Apply();
				}
			}
		}

		private static int Pages()
		{
			return Mathf.Max(1, Mathf.CeilToInt((float)_count / (float)Mathf.Max(1, _pageSize)));
		}

		private static void Apply()
		{
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			GoldSendItem[] array = (Object.op_Implicit((Object)(object)_mgr) ? _mgr.GoldSendItems : null);
			if (array == null || array.Length == 0 || _pageSize <= 0)
			{
				return;
			}
			int num = Pages();
			_page = Mathf.Clamp(_page, 0, num - 1);
			int num2 = _page * _pageSize;
			for (int i = 0; i < array.Length; i++)
			{
				bool flag = i < _count && i >= num2 && i < num2 + _pageSize;
				if (((Component)array[i]).gameObject.activeSelf != flag)
				{
					((Component)array[i]).gameObject.SetActive(flag);
				}
			}
			Transform parent = ((Component)array[0]).transform.parent;
			if (!Object.op_Implicit((Object)(object)parent))
			{
				return;
			}
			Transform val = (Object.op_Implicit((Object)(object)parent.parent) ? parent.parent : parent);
			if (num > 1 && (_nav == null || !_nav.Alive || (Object)(object)((Transform)_nav.Root).parent != (Object)(object)val))
			{
				_nav = new NavBar("GoldNav", val, parent, vertical: false, Step);
				WheelPager wheelPager = ((Component)parent).GetComponent<WheelPager>();
				if (!Object.op_Implicit((Object)(object)wheelPager))
				{
					wheelPager = ((Component)parent).gameObject.AddComponent<WheelPager>();
				}
				wheelPager.OnStep = Step;
			}
			if (_nav == null || !_nav.Alive)
			{
				return;
			}
			_nav.Show(_page, num);
			if (num > 1)
			{
				RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val2 != null)
				{
					Vector3[] array2 = (Vector3[])(object)new Vector3[4];
					val2.GetWorldCorners(array2);
					_nav.PlaceAtWorld((array2[0] + array2[3]) * 0.5f, new Vector2(0.5f, 1f), new Vector2(0f, -6f));
				}
			}
		}
	}
	internal static class EventPager
	{
		private static readonly FieldRef<EventWindow, EventCharacterPortrait[]> PortraitCache = AccessTools.FieldRefAccess<EventWindow, EventCharacterPortrait[]>("_EventCharacterPortraits");

		private static EventWindow _window;

		private static NavBar _nav;

		private static int _count;

		private static int _page;

		public static void EnsureTiles(EventWindow window, int needed)
		{
			if (!Object.op_Implicit((Object)(object)window) || !Object.op_Implicit((Object)(object)window.CharacterImageTileHolder))
			{
				return;
			}
			Transform transform = window.CharacterImageTileHolder.transform;
			int num = 0;
			Transform val = null;
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if (Object.op_Implicit((Object)(object)((Component)child).GetComponent<EventCharacterPortrait>()))
				{
					num++;
					val = child;
				}
			}
			if (!((Object)(object)val == (Object)null) && needed > num)
			{
				int num2 = val.GetSiblingIndex() + 1;
				for (int j = num; j < needed; j++)
				{
					GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, transform);
					((Object)obj).name = ((Object)((Component)val).gameObject).name + " (PLM " + (j + 1) + ")";
					obj.SetActive(false);
					obj.transform.SetSiblingIndex(num2++);
				}
				PortraitCache.Invoke(window) = null;
				PlayerLimitPlugin.Debug($"Event character row grown {num} -> {needed}");
			}
		}

		public static void NewRow(int count)
		{
			_count = count;
			_page = 0;
		}

		public static void Apply(EventWindow window)
		{
			if (!Object.op_Implicit((Object)(object)window) || !Object.op_Implicit((Object)(object)window.CharacterImageTileHolder))
			{
				return;
			}
			_window = window;
			Transform transform = window.CharacterImageTileHolder.transform;
			int eventPortraitsPerPage = PlayerLimitPlugin.EventPortraitsPerPage;
			int num = Mathf.Max(1, Mathf.CeilToInt((float)_count / (float)eventPortraitsPerPage));
			_page = Mathf.Clamp(_page, 0, num - 1);
			int num2 = _page * eventPortraitsPerPage;
			int num3 = 0;
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if (Object.op_Implicit((Object)(object)((Component)child).GetComponent<EventCharacterPortrait>()))
				{
					bool flag = num3 < _count && num3 >= num2 && num3 < num2 + eventPortraitsPerPage;
					if (((Component)child).gameObject.activeSelf != flag)
					{
						((Component)child).gameObject.SetActive(flag);
					}
					num3++;
				}
			}
			UpdateNav(transform, num);
		}

		private static void Step(int delta)
		{
			if (Object.op_Implicit((Object)(object)_window))
			{
				int num = Mathf.Max(1, Mathf.CeilToInt((float)_count / (float)PlayerLimitPlugin.EventPortraitsPerPage));
				int num2 = Mathf.Clamp(_page + delta, 0, num - 1);
				if (num2 != _page)
				{
					_page = num2;
					Apply(_window);
				}
			}
		}

		private static void UpdateNav(Transform holder, int pages)
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (Object.op_Implicit((Object)(object)holder.parent) ? holder.parent : holder);
			if (pages > 1 && (_nav == null || !_nav.Alive || (Object)(object)((Transform)_nav.Root).parent != (Object)(object)val))
			{
				_nav = new NavBar("EventNav", val, holder, vertical: false, Step);
				WheelPager wheelPager = ((Component)holder).GetComponent<WheelPager>();
				if (!Object.op_Implicit((Object)(object)wheelPager))
				{
					wheelPager = ((Component)holder).gameObject.AddComponent<WheelPager>();
				}
				wheelPager.OnStep = Step;
				PlayerLimitPlugin.Debug("Event nav bar created");
			}
			if (_nav == null || !_nav.Alive)
			{
				return;
			}
			_nav.Show(_page, pages);
			if (pages > 1)
			{
				RectTransform val2 = (RectTransform)(object)((holder is RectTransform) ? holder : null);
				if (val2 != null)
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					val2.GetWorldCorners(array);
					Vector3 world = (array[0] + array[3]) * 0.5f;
					_nav.PlaceAtWorld(world, new Vector2(0.5f, 1f), new Vector2(0f, -6f));
				}
			}
		}
	}
	internal static class PartyPager
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__12_0;

			public static UnityAction <>9__12_1;

			internal void <EnsureUi>b__12_0()
			{
				Step(-1);
			}

			internal void <EnsureUi>b__12_1()
			{
				Step(1);
			}
		}

		private static CharacterChoiceManager _mgr;

		private static Transform _panel;

		private static TextMeshProUGUI _counter;

		private static TextMeshProUGUI _pageLabel;

		private static RectTransform _counterBox;

		private static RectTransform _pageBox;

		private static Button _prev;

		private static Button _next;

		private static int _page;

		private static int _lastCount = -1;

		public static void Apply(CharacterChoiceManager mgr)
		{
			if (!Object.op_Implicit((Object)(object)mgr) || !Object.op_Implicit((Object)(object)mgr.partyHolder))
			{
				return;
			}
			List<CharacterChoiceItem> list = PartySelect.PartySlots.Invoke(mgr);
			if (list == null)
			{
				return;
			}
			_mgr = mgr;
			EnsureUi(mgr.partyHolder);
			int num = Mathf.Min(PartySelect.PartyChars.Invoke(mgr)?.Count ?? 0, list.Count);
			int partySlotsPerPage = PlayerLimitPlugin.PartySlotsPerPage;
			int num2 = Mathf.Max(1, Mathf.CeilToInt((float)num / (float)partySlotsPerPage));
			if (_lastCount >= 0 && num > _lastCount)
			{
				_page = num2 - 1;
			}
			_lastCount = num;
			_page = Mathf.Clamp(_page, 0, num2 - 1);
			int num3 = _page * partySlotsPerPage;
			for (int i = 0; i < list.Count; i++)
			{
				CharacterChoiceItem val = list[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					bool flag = i < num && i >= num3 && i < num3 + partySlotsPerPage;
					if (((Component)val).gameObject.activeSelf != flag)
					{
						((Component)val).gameObject.SetActive(flag);
					}
				}
			}
			UpdateUi(num, num2);
		}

		private static void Step(int delta)
		{
			if (Object.op_Implicit((Object)(object)_mgr))
			{
				int num = Mathf.Min(PartySelect.PartyChars.Invoke(_mgr)?.Count ?? 0, PartySelect.PartySlots.Invoke(_mgr)?.Count ?? 0);
				int num2 = Mathf.Max(1, Mathf.CeilToInt((float)num / (float)PlayerLimitPlugin.PartySlotsPerPage));
				int num3 = Mathf.Clamp(_page + delta, 0, num2 - 1);
				if (num3 != _page)
				{
					_page = num3;
					Apply(_mgr);
				}
			}
		}

		private static void EnsureUi(Transform partyHolder)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Expected O, but got Unknown
			Transform parent = partyHolder.parent;
			if (!Object.op_Implicit((Object)(object)parent) || ((Object)(object)_panel == (Object)(object)parent && Object.op_Implicit((Object)(object)_counter) && Object.op_Implicit((Object)(object)_prev)))
			{
				return;
			}
			_panel = parent;
			_counter = UiKit.LabelBox("PartyCounter", parent, parent, out _counterBox);
			((TMP_Text)_counter).alignment = (TextAlignmentOptions)513;
			UiKit.Place(_counterBox, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(104f, 22f), new Vector2(5f, -2f));
			_pageLabel = UiKit.LabelBox("PartyPage", parent, parent, out _pageBox);
			((TMP_Text)_pageLabel).alignment = (TextAlignmentOptions)516;
			UiKit.Place(_pageBox, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(90f, 22f), new Vector2(-5f, -2f));
			Sprite leftArrow = UiKit.LeftArrow;
			Vector2 size = new Vector2(56f, 22f);
			object obj = <>c.<>9__12_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					Step(-1);
				};
				<>c.<>9__12_0 = val;
				obj = (object)val;
			}
			_prev = UiKit.ArrowButton("PartyPrev", parent, leftArrow, 0f, size, (UnityAction)obj);
			UiKit.Place((RectTransform)((Component)_prev).transform, new Vector2(0.35f, 1f), new Vector2(1f, 1f), new Vector2(56f, 22f), new Vector2(-5f, -2f));
			Sprite rightArrow = UiKit.RightArrow;
			Vector2 size2 = new Vector2(56f, 22f);
			object obj2 = <>c.<>9__12_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					Step(1);
				};
				<>c.<>9__12_1 = val2;
				obj2 = (object)val2;
			}
			_next = UiKit.ArrowButton("PartyNext", parent, rightArrow, 0f, size2, (UnityAction)obj2);
			UiKit.Place((RectTransform)((Component)_next).transform, new Vector2(0.65f, 1f), new Vector2(0f, 1f), new Vector2(56f, 22f), new Vector2(5f, -2f));
			WheelPager wheelPager = ((Component)partyHolder).GetComponent<WheelPager>();
			if (!Object.op_Implicit((Object)(object)wheelPager))
			{
				wheelPager = ((Component)partyHolder).gameObject.AddComponent<WheelPager>();
			}
			wheelPager.OnStep = Step;
			PlayerLimitPlugin.Debug("Party pager UI created");
		}

		private static void UpdateUi(int count, int pages)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			int maxPlayers = PlayerLimitPlugin.MaxPlayers;
			if (Object.op_Implicit((Object)(object)_counter))
			{
				((TMP_Text)_counter).text = $"Party: {count}/{maxPlayers}";
				((Graphic)_counter).color = ((count >= maxPlayers) ? UiKit.FullColor : UiKit.TextColor);
			}
			bool active = pages > 1;
			if (Object.op_Implicit((Object)(object)_pageBox))
			{
				((Component)_pageBox).gameObject.SetActive(active);
			}
			if (Object.op_Implicit((Object)(object)_pageLabel))
			{
				((TMP_Text)_pageLabel).text = $"Page {_page + 1}/{pages}";
			}
			if (Object.op_Implicit((Object)(object)_prev))
			{
				((Component)_prev).gameObject.SetActive(active);
				((Selectable)_prev).interactable = _page > 0;
			}
			if (Object.op_Implicit((Object)(object)_next))
			{
				((Component)_next).gameObject.SetActive(active);
				((Selectable)_next).interactable = _page < pages - 1;
			}
		}
	}
	internal static class PortraitPager
	{
		private static PortraitManager _owner;

		private static NavBar _nav;

		private static int _page;

		private static Character _lastSelected;

		private static int _lastPartyCount = -1;

		public static void Update(PortraitManager mgr, ref Portrait[] portraits, List<Character> party)
		{
			if ((Object)(object)_owner != (Object)(object)mgr)
			{
				Reset(mgr);
			}
			int count = party.Count;
			if (count > portraits.Length)
			{
				portraits = Grow(portraits, count);
			}
			int portraitsPerPage = PlayerLimitPlugin.PortraitsPerPage;
			int num = Mathf.Max(1, Mathf.CeilToInt((float)count / (float)portraitsPerPage));
			if (count != _lastPartyCount)
			{
				_lastPartyCount = count;
				_page = Mathf.Clamp(_page, 0, num - 1);
			}
			if (PlayerLimitPlugin.PortraitFollowSelectionEntry.Value && Object.op_Implicit((Object)(object)GameLogic.instance))
			{
				Character currentlySelectedCharacter = GameLogic.instance.CurrentlySelectedCharacter;
				if (currentlySelectedCharacter != null && currentlySelectedCharacter != _lastSelected)
				{
					int num2 = party.IndexOf(currentlySelectedCharacter);
					if (num2 >= 0)
					{
						_page = num2 / portraitsPerPage;
					}
				}
				_lastSelected = currentlySelectedCharacter;
			}
			_page = Mathf.Clamp(_page, 0, num - 1);
			int num3 = _page * portraitsPerPage;
			Portrait val = null;
			for (int i = 0; i < portraits.Length; i++)
			{
				Portrait val2 = portraits[i];
				if (Object.op_Implicit((Object)(object)val2))
				{
					bool num4 = i < count;
					if (num4 && val2.Character != party[i])
					{
						val2.Character = party[i];
					}
					bool flag = num4 && i >= num3 && i < num3 + portraitsPerPage;
					if (((Component)val2).gameObject.activeSelf != flag)
					{
						((Component)val2).gameObject.SetActive(flag);
					}
					if (flag && (Object)(object)val == (Object)null)
					{
						val = val2;
					}
				}
			}
			UpdateNav(mgr, num, val);
		}

		private static void Reset(PortraitManager mgr)
		{
			_owner = mgr;
			_page = 0;
			_lastSelected = null;
			_lastPartyCount = -1;
			_nav = null;
		}

		private static Portrait[] Grow(Portrait[] portraits, int needed)
		{
			Portrait val = portraits[0];
			if (!Object.op_Implicit((Object)(object)val))
			{
				return portraits;
			}
			Transform parent = ((Component)val).transform.parent;
			Portrait[] array = (Portrait[])(object)new Portrait[needed];
			Array.Copy(portraits, array, portraits.Length);
			int num = (Object.op_Implicit((Object)(object)portraits[^1]) ? (((Component)portraits[^1]).transform.GetSiblingIndex() + 1) : parent.childCount);
			for (int i = portraits.Length; i < needed; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)val2).name = ((Object)((Component)val).gameObject).name + " (PLM " + (i + 1) + ")";
				val2.SetActive(false);
				val2.transform.SetSiblingIndex(num++);
				array[i] = val2.GetComponent<Portrait>();
			}
			PlayerLimitPlugin.Debug($"Portrait column grown {portraits.Length} -> {needed}");
			return array;
		}

		private static void Step(int delta)
		{
			_page = Mathf.Max(0, _page + delta);
			_lastSelected = (Object.op_Implicit((Object)(object)GameLogic.instance) ? GameLogic.instance.CurrentlySelectedCharacter : null);
		}

		private static void UpdateNav(PortraitManager mgr, int pages, Portrait firstShown)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (pages > 1 && (_nav == null || !_nav.Alive))
			{
				_nav = new NavBar("PortraitNav", ((Component)mgr).transform, ((Component)mgr).transform, vertical: true, Step);
				WheelPager wheelPager = ((Component)mgr).GetComponent<WheelPager>();
				if (!Object.op_Implicit((Object)(object)wheelPager))
				{
					wheelPager = ((Component)mgr).gameObject.AddComponent<WheelPager>();
				}
				wheelPager.OnStep = Step;
				PlayerLimitPlugin.Debug("Portrait nav bar created");
			}
			if (_nav != null && _nav.Alive)
			{
				_nav.Show(_page, pages);
				if (pages > 1 && Object.op_Implicit((Object)(object)firstShown))
				{
					RectTransform val = (RectTransform)((Component)firstShown).transform;
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					val.GetWorldCorners(array);
					_nav.PlaceAtWorld(array[1], new Vector2(0f, 0f), new Vector2(0f, 6f));
				}
			}
		}
	}
	internal static class UiKit
	{
		public static readonly Color BoxColor = new Color(0.08f, 0.07f, 0.06f, 0.85f);

		public static readonly Color TextColor = new Color(0.92f, 0.86f, 0.7f);

		public static readonly Color FullColor = new Color(0.95f, 0.45f, 0.35f);

		private static Sprite _left;

		private static Sprite _right;

		private static TMP_FontAsset _font;

		public static Sprite LeftArrow
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_left))
				{
					return _left = LoadSprite("arrow_left.png");
				}
				return _left;
			}
		}

		public static Sprite RightArrow
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_right))
				{
					return _right = LoadSprite("arrow_right.png");
				}
				return _right;
			}
		}

		public static TMP_FontAsset Font(Transform root)
		{
			if (Object.op_Implicit((Object)(object)_font))
			{
				return _font;
			}
			if (!Object.op_Implicit((Object)(object)root))
			{
				return null;
			}
			TMP_Text[] componentsInChildren = ((Component)root).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.font))
				{
					_font = val.font;
					break;
				}
			}
			return _font;
		}

		private static Sprite LoadSprite(string resource)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				using Stream stream = typeof(UiKit).Assembly.GetManifestResourceStream(resource);
				if (stream == null)
				{
					return null;
				}
				byte[] array = new byte[stream.Length];
				for (int i = 0; i < array.Length; i += stream.Read(array, i, array.Length - i))
				{
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					filterMode = (FilterMode)1
				};
				ImageConversion.LoadImage(val, array);
				Object.DontDestroyOnLoad((Object)(object)val);
				Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				Object.DontDestroyOnLoad((Object)(object)obj);
				return obj;
			}
			catch (Exception ex)
			{
				PlayerLimitPlugin.Log.LogWarning((object)("Could not load " + resource + ": " + ex.Message));
				return null;
			}
		}

		public static RectTransform Rect(string name, Transform parent)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0047: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject("PLM_" + name, new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)parent).gameObject.layer
			}.transform;
			((Transform)val).SetParent(parent, false);
			return val;
		}

		public static void Place(RectTransform rt, Vector2 anchor, Vector2 pivot, Vector2 size, Vector2 pos)
		{
			//IL_0001: 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_000f: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = anchor;
			rt.anchorMax = anchor;
			rt.pivot = pivot;
			rt.sizeDelta = size;
			rt.anchoredPosition = pos;
		}

		public static TextMeshProUGUI LabelBox(string name, Transform parent, Transform fontSource, out RectTransform box)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0053: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			box = Rect(name, parent);
			Image obj = ((Component)box).gameObject.AddComponent<Image>();
			((Graphic)obj).color = BoxColor;
			((Graphic)obj).raycastTarget = false;
			RectTransform obj2 = Rect("Text", (Transform)(object)box);
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(6f, 1f);
			obj2.offsetMax = new Vector2(-6f, -1f);
			TextMeshProUGUI val = ((Component)obj2).gameObject.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset val2 = Font(fontSource);
			if (Object.op_Implicit((Object)(object)val2))
			{
				((TMP_Text)val).font = val2;
			}
			((TMP_Text)val).fontSize = 13f;
			((Graphic)val).color = TextColor;
			((TMP_Text)val).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val).overflowMode = (TextOverflowModes)0;
			((Graphic)val).raycastTarget = false;
			return val;
		}

		public static Button ArrowButton(string name, Transform parent, Sprite sprite, float rotationZ, Vector2 size, UnityAction onClick)
		{
			//IL_0009: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Rect(name, parent);
			val.sizeDelta = size;
			Image val2 = ((Component)val).gameObject.AddComponent<Image>();
			if (Object.op_Implicit((Object)(object)sprite))
			{
				val2.sprite = sprite;
				val2.preserveAspect = true;
			}
			else
			{
				((Graphic)val2).color = BoxColor;
			}
			if (Math.Abs(rotationZ) > 0.01f)
			{
				RectTransform obj = Rect("Gfx", (Transform)(object)val);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(0.5f, 0.5f);
				obj.anchorMax = val3;
				obj.anchorMin = val3;
				obj.sizeDelta = new Vector2(size.y, size.x);
				((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, rotationZ);
				Image obj2 = ((Component)obj).gameObject.AddComponent<Image>();
				obj2.sprite = val2.sprite;
				obj2.preserveAspect = true;
				((Graphic)obj2).raycastTarget = false;
				val2.sprite = null;
				((Graphic)val2).color = new Color(0f, 0f, 0f, 0.001f);
				val2 = obj2;
			}
			Button obj3 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj3).targetGraphic = (Graphic)(object)val2;
			ColorBlock colors = ((Selectable)obj3).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.9f, 0.7f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.7f, 0.6f, 0.4f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.45f, 0.45f, 0.45f, 0.6f);
			((ColorBlock)(ref colors)).fadeDuration = 0.08f;
			((Selectable)obj3).colors = colors;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj3).navigation = navigation;
			((UnityEvent)obj3.onClick).AddListener(onClick);
			return obj3;
		}
	}
	internal class NavBar
	{
		public RectTransform Root;

		private readonly Button _prev;

		private readonly Button _next;

		private readonly TextMeshProUGUI _label;

		private readonly bool _vertical;

		public bool Alive => Object.op_Implicit((Object)(object)Root);

		public NavBar(string name, Transform parent, Transform fontSource, bool vertical, Action<int> step)
		{
			//IL_003b: 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_0040: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			_vertical = vertical;
			Vector2 val = (vertical ? new Vector2(24f, 28f) : new Vector2(52f, 24f));
			float num = (vertical ? 44f : 84f);
			float num2 = (vertical ? 32f : 30f);
			float num3 = 6f + val.x + 4f + num + 4f + val.x + 6f;
			Root = UiKit.Rect(name, parent);
			((Component)Root).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
			RectTransform root = Root;
			RectTransform root2 = Root;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			root2.anchorMax = val2;
			root.anchorMin = val2;
			Root.sizeDelta = new Vector2(num3, num2);
			Image obj = ((Component)Root).gameObject.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.06f, 0.05f, 0.04f, 0.92f);
			((Graphic)obj).raycastTarget = true;
			Outline obj2 = ((Component)Root).gameObject.AddComponent<Outline>();
			((Shadow)obj2).effectColor = new Color(0.87f, 0.67f, 0.27f, 0.9f);
			((Shadow)obj2).effectDistance = new Vector2(1.5f, -1.5f);
			_prev = UiKit.ArrowButton(name + "Prev", (Transform)(object)Root, vertical ? UiKit.RightArrow : UiKit.LeftArrow, vertical ? 90f : 0f, val, (UnityAction)delegate
			{
				step(-1);
			});
			UiKit.Place((RectTransform)((Component)_prev).transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), val, new Vector2(6f, 0f));
			_next = UiKit.ArrowButton(name + "Next", (Transform)(object)Root, UiKit.RightArrow, vertical ? (-90f) : 0f, val, (UnityAction)delegate
			{
				step(1);
			});
			UiKit.Place((RectTransform)((Component)_next).transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), val, new Vector2(-6f, 0f));
			RectTransform val3 = UiKit.Rect(name + "Label", (Transform)(object)Root);
			UiKit.Place(val3, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(num, num2), Vector2.zero);
			_label = ((Component)val3).gameObject.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset val4 = UiKit.Font(fontSource);
			if (Object.op_Implicit((Object)(object)val4))
			{
				((TMP_Text)_label).font = val4;
			}
			((TMP_Text)_label).fontSize = 15f;
			((Graphic)_label).color = UiKit.TextColor;
			((TMP_Text)_label).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_label).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)_label).overflowMode = (TextOverflowModes)0;
			((Graphic)_label).raycastTarget = false;
			((Component)Root).gameObject.AddComponent<WheelPager>().OnStep = step;
		}

		public void Show(int page, int pages)
		{
			if (Object.op_Implicit((Object)(object)Root))
			{
				bool flag = pages > 1;
				if (((Component)Root).gameObject.activeSelf != flag)
				{
					((Component)Root).gameObject.SetActive(flag);
				}
				if (flag)
				{
					((TMP_Text)_label).text = (_vertical ? $"{page + 1}/{pages}" : $"Page {page + 1}/{pages}");
					((Selectable)_prev).interactable = page > 0;
					((Selectable)_next).interactable = page < pages - 1;
					((Transform)Root).SetAsLastSibling();
				}
			}
		}

		public void PlaceAtWorld(Vector3 world, Vector2 pivot, Vector2 offset, float minScale = 0.55f)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0061: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Root) && Object.op_Implicit((Object)(object)((Transform)Root).parent))
			{
				Root.pivot = pivot;
				((Transform)Root).localScale = Vector3.one;
				Vector3 val = ((Transform)Root).parent.InverseTransformPoint(world);
				((Transform)Root).localPosition = new Vector3(val.x + offset.x, val.y + offset.y, 0f);
				FitOnScreen(minScale);
			}
		}

		private void FitOnScreen(float minScale)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			Canvas componentInParent = ((Component)Root).GetComponentInParent<Canvas>();
			Camera cam = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
			Rect val = ScreenRect();
			if (!(((Rect)(ref val)).height <= 0f) && !(((Rect)(ref val)).width <= 0f))
			{
				float num = ((Root.pivot.y <= 0.01f) ? ((float)Screen.height - 4f - ((Rect)(ref val)).yMin) : ((!(Root.pivot.y >= 0.99f)) ? ((float)Screen.height - 8f) : (((Rect)(ref val)).yMax - 4f)));
				if (((Rect)(ref val)).height > num && num > 0f)
				{
					float num2 = Mathf.Clamp(num / ((Rect)(ref val)).height, minScale, 1f);
					((Transform)Root).localScale = new Vector3(num2, num2, 1f);
					val = ScreenRect();
				}
				float num3 = 0f;
				float num4 = 0f;
				if (((Rect)(ref val)).xMin < 4f)
				{
					num3 = 4f - ((Rect)(ref val)).xMin;
				}
				else if (((Rect)(ref val)).xMax > (float)Screen.width - 4f)
				{
					num3 = (float)Screen.width - 4f - ((Rect)(ref val)).xMax;
				}
				if (((Rect)(ref val)).yMax > (float)Screen.height - 4f)
				{
					num4 = (float)Screen.height - 4f - ((Rect)(ref val)).yMax;
				}
				else if (((Rect)(ref val)).yMin < 4f)
				{
					num4 = 4f - ((Rect)(ref val)).yMin;
				}
				if (num3 != 0f || num4 != 0f)
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					Root.GetWorldCorners(array);
					float num5 = (array[2].x - array[0].x) / ((Rect)(ref val)).width;
					float num6 = (array[2].y - array[0].y) / ((Rect)(ref val)).height;
					RectTransform root = Root;
					((Transform)root).position = ((Transform)root).position + new Vector3(num3 * num5, num4 * num6, 0f);
				}
			}
			Rect ScreenRect()
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: 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_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				Root.GetWorldCorners(array2);
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(cam, array2[0]);
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(cam, array2[2]);
				return Rect.MinMaxRect(val2.x, val2.y, val3.x, val3.y);
			}
		}
	}
	internal class WheelPager : MonoBehaviour, IScrollHandler, IEventSystemHandler
	{
		public Action<int> OnStep;

		public void OnScroll(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			float y = eventData.scrollDelta.y;
			if (!(Mathf.Abs(y) < 0.01f))
			{
				OnStep?.Invoke((!(y > 0f)) ? 1 : (-1));
			}
		}
	}
}
namespace PlayerLimitMod.Patches
{
	[HarmonyPatch(typeof(GameLogic), "SetupBattleInfo")]
	internal static class Enemies_MoreForBigParties
	{
		private static void Prefix(BattleInfo battle, ref int pointsToSpend)
		{
			if (pointsToSpend > 0 && !((Object)(object)battle == (Object)null))
			{
				int num = Bonus();
				if (num > 0)
				{
					pointsToSpend += num;
					PlayerLimitPlugin.Debug($"Battle points {pointsToSpend - num} -> {pointsToSpend} (+{num} for {Arrays.PartyCount()} heroes)");
				}
			}
		}

		public static int Bonus()
		{
			float extraEnemyPointsPerHero = PlayerLimitPlugin.ExtraEnemyPointsPerHero;
			int num = Arrays.PartyCount() - 6;
			if (extraEnemyPointsPerHero <= 0f || num <= 0)
			{
				return 0;
			}
			return Mathf.RoundToInt((float)num * extraEnemyPointsPerHero);
		}
	}
	[HarmonyPatch(typeof(GameLogic), "GetSpawnPoint")]
	internal static class Enemies_SpawnFallback
	{
		private static void Postfix(GameLogic __instance, List<HexCell> cells, ref HexCell __result)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			if ((Object)(object)__result != (Object)null)
			{
				return;
			}
			RoomInfo val = (Object.op_Implicit((Object)(object)WorldMapGenerator.instance) ? WorldMapGenerator.instance.CurrentRoom : null);
			List<HexCell> list = ((val != null) ? val.Hexes : null);
			if (list != null && list.Count != 0)
			{
				Vector3 centre = ((cells != null && cells.Count > 0 && Object.op_Implicit((Object)(object)cells[0])) ? ((Component)cells[0]).transform.position : Vector3.zero);
				__result = list.Where((HexCell h) => Object.op_Implicit((Object)(object)h) && h.IsValid && h.IsWalkable && !__instance.SpawnHexUsed(h, true)).OrderBy(delegate(HexCell h)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//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)
					Vector3 val2 = ((Component)h).transform.position - centre;
					return ((Vector3)(ref val2)).sqrMagnitude;
				}).FirstOrDefault();
				if ((Object)(object)__result != (Object)null)
				{
					PlayerLimitPlugin.Debug("Enemy spawn area full; used a nearby free hex");
				}
				else
				{
					PlayerLimitPlugin.Log.LogWarning((object)"No free hex left in the room for an enemy spawn");
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class Event_CharacterRow
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(EventWindow), "ChooseCharacter", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(EventWindow), "ChooseOptionAsParty", (Type[])null, (Type[])null);
		}

		private static void Prefix(EventWindow __instance, object[] __args)
		{
			int num = ((__args.Length > 1 && __args[1] is IList list) ? list.Count : 0);
			EventPager.EnsureTiles(__instance, num);
			EventPager.NewRow(num);
		}

		private static void Postfix(EventWindow __instance)
		{
			EventPager.Apply(__instance);
		}
	}
	[HarmonyPatch(typeof(VotingColorTiles), "UpdateTiles")]
	internal static class Event_VoteDots
	{
		private static void Prefix(VotingColorTiles __instance, List<int> activeIndicies)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (activeIndicies == null || activeIndicies.Count == 0)
			{
				return;
			}
			int num = activeIndicies.Max() + 1;
			Transform transform = ((Component)__instance).transform;
			if (transform.childCount == 0 || num <= transform.childCount)
			{
				return;
			}
			Palette.Ensure();
			List<Color> list = (Object.op_Implicit((Object)(object)GUIManager.instance) ? GUIManager.instance.ConnectionColors : null);
			GameObject gameObject = ((Component)transform.GetChild(transform.childCount - 1)).gameObject;
			for (int i = transform.childCount; i < num; i++)
			{
				GameObject obj = Object.Instantiate<GameObject>(gameObject, transform);
				((Object)obj).name = ((Object)gameObject).name + " (PLM " + (i + 1) + ")";
				Image component = obj.GetComponent<Image>();
				if (Object.op_Implicit((Object)(object)component) && list != null && i < list.Count)
				{
					((Graphic)component).color = list[i];
				}
			}
		}
	}
	internal static class EventResultRows
	{
		public static void Ensure(EventWindow window)
		{
			if (!Object.op_Implicit((Object)(object)window))
			{
				return;
			}
			AllCharactersResultItem[] allCharactersResultItems = window.AllCharactersResultItems;
			if (allCharactersResultItems == null || allCharactersResultItems.Length == 0)
			{
				return;
			}
			NetworkingManager instance = NetworkingManager.Instance;
			int valueOrDefault = ((instance == null) ? ((int?)null) : instance.PartyCharacters?.Count).GetValueOrDefault();
			if (allCharactersResultItems.Length < valueOrDefault)
			{
				AllCharactersResultItem val = allCharactersResultItems[^1];
				Transform parent = ((Component)val).transform.parent;
				AllCharactersResultItem[] array = (AllCharactersResultItem[])(object)new AllCharactersResultItem[valueOrDefault];
				Array.Copy(allCharactersResultItems, array, allCharactersResultItems.Length);
				int num = ((Component)val).transform.GetSiblingIndex() + 1;
				for (int i = allCharactersResultItems.Length; i < valueOrDefault; i++)
				{
					GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
					((Object)obj).name = ((Object)((Component)val).gameObject).name + " (PLM " + (i + 1) + ")";
					obj.SetActive(false);
					obj.transform.SetSiblingIndex(num++);
					AllCharactersResultItem component = obj.GetComponent<AllCharactersResultItem>();
					component.Character = null;
					array[i] = component;
				}
				window.AllCharactersResultItems = array;
				PlayerLimitPlugin.Debug($"Event result rows grown {allCharactersResultItems.Length} -> {valueOrDefault}");
			}
		}
	}
	[HarmonyPatch(typeof(EventWindow), "ExecuteStartEvent")]
	internal static class Event_ResultRows_Start
	{
		private static void Prefix(EventWindow __instance)
		{
			EventResultRows.Ensure(__instance);
		}
	}
	[HarmonyPatch(typeof(EventOptionSelectionItem), "ShowAllCharacterResultEffectText")]
	internal static class Event_ResultRows_Show
	{
		private static void Prefix()
		{
			EventResultRows.Ensure(LoadableUIWindow<EventWindow>.Instance);
		}
	}
	internal static class Arrays
	{
		public static int[] PadWithLast(int[] table, int length, string what)
		{
			if (table == null || table.Length == 0 || table.Length >= length)
			{
				return table;
			}
			int[] array = new int[length];
			Array.Copy(table, array, table.Length);
			for (int i = table.Length; i < length; i++)
			{
				array[i] = table[^1];
			}
			PlayerLimitPlugin.Debug($"{what}: extended {table.Length} -> {length} entries");
			return array;
		}

		public static int PartyCount()
		{
			NetworkingManager instance = NetworkingManager.Instance;
			return ((instance == null) ? ((int?)null) : instance.PartyCharacters?.Count).GetValueOrDefault();
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class Event_DiceModifierTable
	{
		private static void Prefix()
		{
			DiceRollingManager instance = DiceRollingManager.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				int length = Mathf.Max(PlayerLimitPlugin.MaxPlayers, Arrays.PartyCount());
				instance.PartyCountRollModifiers = Arrays.PadWithLast(instance.PartyCountRollModifiers, length, "PartyCountRollModifiers");
			}
		}
	}
	[HarmonyPatch(typeof(BattleManager), "CheckBattleDrops")]
	internal static class Battle_DropTable
	{
		private static void Prefix(BattleManager __instance)
		{
			int length = Mathf.Max(PlayerLimitPlugin.MaxPlayers, Arrays.PartyCount());
			__instance.BattleDropSpawnCountPerPlayer = Arrays.PadWithLast(__instance.BattleDropSpawnCountPerPlayer, length, "BattleDropSpawnCountPerPlayer");
		}
	}
	internal static class Palette
	{
		public static void Ensure()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.instance;
			if (!Object.op_Implicit((Object)(object)instance) || instance.ConnectionColors == null || instance.ConnectionColors.Count == 0)
			{
				return;
			}
			int num = Mathf.Max(36, PlayerLimitPlugin.MaxPlayers * 6);
			List<Color> connectionColors = instance.ConnectionColors;
			if (connectionColors.Count < num)
			{
				for (int i = connectionColors.Count; i < num; i++)
				{
					float num2 = (0.13f + (float)i * 0.618034f) % 1f;
					float num3 = ((i / 6 % 2 == 0) ? 0.7f : 0.5f);
					connectionColors.Add(Color.HSVToRGB(num2, num3, 0.95f));
				}
				PlayerLimitPlugin.Debug($"ConnectionColors extended to {connectionColors.Count}");
			}
		}
	}
	[HarmonyPatch(typeof(Root), "GetPlayerControllerColor")]
	internal static class Colors_PlayerControllerColor
	{
		private static bool Prefix(Root __instance, int owner, int controllerPlayerId, ref Color __result)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			Palette.Ensure();
			if (controllerPlayerId >= 6)
			{
				return true;
			}
			int num = ((IEnumerable<KeyValuePair<int, bool>>)__instance.ActiveConnections).Count((KeyValuePair<int, bool> kv) => kv.Key < owner);
			if (num < 6)
			{
				return true;
			}
			List<Color> connectionColors = GUIManager.instance.ConnectionColors;
			int num2 = num * 6 + controllerPlayerId;
			__result = ((num2 < connectionColors.Count) ? connectionColors[num2] : GUIManager.instance.NoCharacterColor);
			return false;
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class Colors_PartyCharactersColor
	{
		private static void Prefix()
		{
			Palette.Ensure();
		}
	}
	[HarmonyPatch(typeof(GoldSendManager), "ShowGoldSendWindow")]
	internal static class Gold_SendWindow
	{
		private static readonly FieldRef<GoldSendManager, GoldSendItem[]> Cache = AccessTools.FieldRefAccess<GoldSendManager, GoldSendItem[]>("_GoldSendItems");

		private static void Prefix(GoldSendManager __instance)
		{
			GoldSendItem[] goldSendItems = __instance.GoldSendItems;
			if (goldSendItems == null || goldSendItems.Length == 0)
			{
				return;
			}
			GoldPager.RememberPageSize(goldSendItems.Length);
			Character sender = (Object.op_Implicit((Object)(object)GameLogic.instance) ? GameLogic.instance.CurrentlySelectedCharacter : null);
			NetworkingManager instance = NetworkingManager.Instance;
			int valueOrDefault = ((instance == null) ? ((int?)null) : instance.PartyCharacters?.Count((Character c) => c != sender)).GetValueOrDefault();
			if (valueOrDefault > goldSendItems.Length)
			{
				GoldSendItem val = goldSendItems[^1];
				Transform parent = ((Component)val).transform.parent;
				int num = ((Component)val).transform.GetSiblingIndex() + 1;
				for (int num2 = goldSendItems.Length; num2 < valueOrDefault; num2++)
				{
					GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
					((Object)obj).name = ((Object)((Component)val).gameObject).name + " (PLM " + (num2 + 1) + ")";
					obj.SetActive(false);
					obj.transform.SetSiblingIndex(num++);
				}
				Cache.Invoke(__instance) = null;
				PlayerLimitPlugin.Debug($"Gold recipient list grown {goldSendItems.Length} -> {valueOrDefault}");
			}
		}

		private static void Postfix(GoldSendManager __instance)
		{
			Character sender = (Object.op_Implicit((Object)(object)GameLogic.instance) ? GameLogic.instance.CurrentlySelectedCharacter : null);
			NetworkingManager instance = NetworkingManager.Instance;
			int valueOrDefault = ((instance == null) ? ((int?)null) : instance.PartyCharacters?.Count((Character c) => c != sender)).GetValueOrDefault();
			GoldPager.Open(__instance, valueOrDefault);
		}
	}
	[HarmonyPatch(typeof(ItemRightClick), "ShowRightClickTooltip", new Type[]
	{
		typeof(Character),
		typeof(ItemSlot)
	})]
	internal static class Inventory_RightClickMenu
	{
		private const int FixedEntries = 6;

		private static void Prefix(ItemRightClick __instance)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			ItemRightClickOption[] options = __instance.Options;
			if (options == null || options.Length == 0)
			{
				return;
			}
			NetworkingManager instance = NetworkingManager.Instance;
			int num = ((instance == null) ? ((int?)null) : instance.PartyCharacters?.Count).GetValueOrDefault() + 6;
			if (options.Length >= num)
			{
				return;
			}
			ItemRightClickOption val = options[^1];
			Transform parent = ((Component)val).transform.parent;
			ItemRightClickOption[] array = (ItemRightClickOption[])(object)new ItemRightClickOption[num];
			Array.Copy(options, array, options.Length);
			bool flag = Object.op_Implicit((Object)(object)parent) && Object.op_Implicit((Object)(object)((Component)parent).GetComponent<LayoutGroup>());
			Vector2 anchoredPosition = ((RectTransform)((Component)val).transform).anchoredPosition;
			? val2;
			if (options.Length <= 1)
			{
				Rect rect = ((RectTransform)((Component)val).transform).rect;
				val2 = new Vector2(0f, 0f - ((Rect)(ref rect)).height);
			}
			else
			{
				val2 = anchoredPosition - ((RectTransform)((Component)options[^2]).transform).anchoredPosition;
			}
			Vector2 val3 = (Vector2)val2;
			int num2 = ((Component)val).transform.GetSiblingIndex() + 1;
			for (int i = options.Length; i < num; i++)
			{
				GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)val4).name = ((Object)((Component)val).gameObject).name + " (PLM " + (i + 1) + ")";
				val4.SetActive(false);
				val4.transform.SetSiblingIndex(num2++);
				if (!flag)
				{
					((RectTransform)val4.transform).anchoredPosition = anchoredPosition + val3 * (float)(i - options.Length + 1);
				}
				array[i] = val4.GetComponent<ItemRightClickOption>();
			}
			__instance.Options = array;
			PlayerLimitPlugin.Debug($"Item right-click menu grown {options.Length} -> {num} options");
		}

		private static void Postfix(ItemRightClick __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			OnScreen.Clamp((RectTransform)((Component)__instance).transform);
		}
	}
	internal static class OnScreen
	{
		public static void Clamp(RectTransform rt)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0057: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_00c1: 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_00ea: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)rt) || !((Component)rt).gameObject.activeInHierarchy)
			{
				return;
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
			Canvas componentInParent = ((Component)rt).GetComponentInParent<Canvas>();
			Camera obj = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rt.GetWorldCorners(array);
			Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, array[0]);
			Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[2]);
			float num = val2.x - val.x;
			float num2 = val2.y - val.y;
			if (!(num <= 0f) && !(num2 <= 0f))
			{
				float num3 = 0f;
				float num4 = 0f;
				if (val.y < 8f)
				{
					num4 = 8f - val.y;
				}
				else if (val2.y > (float)Screen.height - 8f)
				{
					num4 = (float)Screen.height - 8f - val2.y;
				}
				if (val2.x > (float)Screen.width - 8f)
				{
					num3 = (float)Screen.width - 8f - val2.x;
				}
				if (num3 != 0f || num4 != 0f)
				{
					float num5 = (array[2].x - array[0].x) / num;
					float num6 = (array[2].y - array[0].y) / num2;
					((Transform)rt).position = ((Transform)rt).position + new Vector3(num3 * num5, num4 * num6, 0f);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class Lobby_Steam
	{
		private static MethodBase TargetMethod()
		{
			return Il.StateMachineMoveNext(typeof(MainMenu), "CreateSteamLobby");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Il.ReplaceSix(code, Il.FeedsCall("CreateLobbyAsync", "set_MaxMembers"), 2, "MainMenu.CreateSteamLobby");
		}
	}
	[HarmonyPatch]
	internal static class Lobby_PlayFab
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from m in typeof(PlayFabMultiplayer).GetMethods(BindingFlags.Static | BindingFlags.Public)
				where m.Name == "CreateAndJoinLobby" && m.GetParameters().Any((ParameterInfo p) => p.ParameterType == typeof(LobbyCreateConfiguration))
				select m;
		}

		private static void Prefix(LobbyCreateConfiguration createConfiguration)
		{
			if (createConfiguration != null)
			{
				uint num = (uint)PlayerLimitPlugin.MaxPlayers;
				uint num2 = ReadLimit("LobbyMaxMemberCountLowerLimit", 2u);
				uint num3 = ReadLimit("LobbyMaxMemberCountUpperLimit", 128u);
				if (num < num2)
				{
					num = num2;
				}
				if (num > num3)
				{
					num = num3;
				}
				createConfiguration.MaxMemberCount = num;
				PlayerLimitPlugin.Debug($"PlayFab lobby MaxMemberCount -> {num}");
			}
		}

		private static uint ReadLimit(string field, uint fallback)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(PlayFabMultiplayer), field);
				if (fieldInfo != null && fieldInfo.GetValue(null) is uint num && num != 0)
				{
					return num;
				}
			}
			catch
			{
			}
			return fallback;
		}
	}
	internal static class PartySelect
	{
		internal static readonly FieldRef<CharacterChoiceManager, int> PartyMax = AccessTools.FieldRefAccess<CharacterChoiceManager, int>("partyMax");

		internal static readonly FieldRef<CharacterChoiceManager, List<CharacterChoiceItem>> PartySlots = AccessTools.FieldRefAccess<CharacterChoiceManager, List<CharacterChoiceItem>>("partySlots");

		internal static readonly FieldRef<CharacterChoiceManager, List<Character>> PartyChars = AccessTools.FieldRefAccess<CharacterChoiceManager, List<Character>>("partyChars");

		internal static void ApplyPartyMax(CharacterChoiceManager mgr)
		{
			if ((Object)(object)mgr != (Object)null)
			{
				PartyMax.Invoke(mgr) = PlayerLimitPlugin.MaxPlayers;
			}
		}
	}
	[HarmonyPatch]
	internal static class PartySelect_PartyMax
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(CharacterChoiceManager), "Start", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(CharacterChoiceManager), "RefreshCharacters", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(CharacterChoiceManager), "ToggleSelectedCharacter", (Type[])null, (Type[])null);
		}

		private static void Prefix(CharacterChoiceManager __instance)
		{
			PartySelect.ApplyPartyMax(__instance);
		}
	}
	[HarmonyPatch(typeof(CharacterChoiceManager), "Update")]
	internal static class PartySelect_UpdateAcceptButton
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Il.ReplaceSix(code, Il.FeedsComparison, 1, "CharacterChoiceManager.Update");
		}
	}
	[HarmonyPatch]
	internal static class PartySelect_RefreshCoroutine
	{
		private static FieldInfo _thisField;

		private static MethodBase TargetMethod()
		{
			return Il.StateMachineMoveNext(typeof(CharacterChoiceManager), "ExecuteRefreshCharacters");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Il.ReplaceSix(code, Il.FeedsComparison, 2, "CharacterChoiceManager.ExecuteRefreshCharacters");
		}

		private static void Postfix(object __instance, bool __result)
		{
			if (!__result)
			{
				if (_thisField == null)
				{
					_thisField = AccessTools.Field(__instance.GetType(), "<>4__this");
				}
				object? obj = _thisField?.GetValue(__instance);
				CharacterChoiceManager val = (CharacterChoiceManager)((obj is CharacterChoiceManager) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					PartyPager.Apply(val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterChoiceItem), "MouseOver")]
	internal static class PartySelect_MouseOverHint
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Il.ReplaceSix(code, Il.FeedsComparison, 1, "CharacterChoiceItem.MouseOver");
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class Roster_CharacterLimit
	{
		private static void Postfix(ref int __result)
		{
			if (__result < PlayerLimitPlugin.MaxPlayers)
			{
				__result = PlayerLimitPlugin.MaxPlayers;
			}
		}
	}
	[HarmonyPatch(typeof(PortraitManager), "UpdatePortraits")]
	internal static class Portraits_Update
	{
		internal static readonly FieldRef<PortraitManager, Portrait[]> Portraits = AccessTools.FieldRefAccess<PortraitManager, Portrait[]>("portraits");

		private static bool Prefix(PortraitManager __instance)
		{
			NetworkingManager instance = NetworkingManager.Instance;
			List<Character> list = ((instance != null) ? instance.PartyCharacters : null);
			if (list == null)
			{
				return false;
			}
			ref Portrait[] reference = ref Portraits.Invoke(__instance);
			if (reference == null || reference.Length == 0)
			{
				return true;
			}
			PortraitPager.Update(__instance, ref reference, list);
			return false;
		}
	}
	internal static class XpBars
	{
		public static bool Ensure(Component root, string where)
		{
			if (!PlayerLimitPlugin.ExtraRewardBarsEntry.Value || !Object.op_Implicit((Object)(object)GameLogic.instance) || !Object.op_Implicit((Object)(object)root))
			{
				return false;
			}
			int num = GameLogic.instance.ControlledCharacters?.Count() ?? 0;
			CharXpMeter[] componentsInChildren = root.GetComponentsInChildren<CharXpMeter>(true);
			if (componentsInChildren.Length == 0 || num <= componentsInChildren.Length)
			{
				return false;
			}
			CharXpMeter val = componentsInChildren[^1];
			Transform parent = ((Component)val).transform.parent;
			if (!Object.op_Implicit((Object)(object)parent) || !Object.op_Implicit((Object)(object)((Component)parent).GetComponent<LayoutGroup>()))
			{
				PlayerLimitPlugin.Debug(where + ": XP bars are not in a layout group; leaving them alone");
				return false;
			}
			for (int i = componentsInChildren.Length; i < num; i++)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, parent);
				((Object)obj).name = ((Object)((Component)val).gameObject).name + " (PLM " + (i + 1) + ")";
				obj.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + (i - componentsInChildren.Length) + 1);
			}
			PlayerLimitPlugin.Debug($"{where}: added {num - componentsInChildren.Length} XP bars");
			return true;
		}
	}
	[HarmonyPatch(typeof(AdventureRewards), "ExecuteOpenAdventureRewards")]
	internal static class Rewards_ExtraXpBars
	{
		private static void Prefix(AdventureRewards __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			XpBars.Ensure((Component)__instance, "Adventure results");
		}
	}
	[HarmonyPatch(typeof(PostBattleManager), "OpenPostBattleMenu")]
	internal static class PostBattle_ExtraXpBars
	{
		private static readonly FieldRef<PostBattleManager, CharXpMeter[]> Meters = AccessTools.FieldRefAccess<PostBattleManager, CharXpMeter[]>("xpMeters");

		private static void Prefix(PostBattleManager __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			Component val = (Component)__instance;
			if (XpBars.Ensure(val, "Post-battle"))
			{
				Meters.Invoke(__instance) = val.GetComponentsInChildren<CharXpMeter>(true);
			}
		}
	}
}