Decompiled source of LobbyExpansion v1.1.0

GTFO.LobbyExpansion.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using AIGraph;
using AK;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using BoosterImplants;
using CellMenu;
using ChainedPuzzles;
using Enemies;
using GTFO.LobbyExpansion.Patches.Manual;
using GTFO.LobbyExpansion.Util;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Common;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;
using PlayerCoverage;
using SNetwork;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GTFO.LobbyExpansion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+3a6479d1f1454e69cb86c099d41e95902d0d59c9")]
[assembly: AssemblyProduct("GTFO.LobbyExpansion")]
[assembly: AssemblyTitle("GTFO.LobbyExpansion")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GTFO.LobbyExpansion
{
	public static class CoolButton
	{
		private const float ALPHA_OVER = 1f;

		private const float ALPHA_OVER_DISABLED = 0.25f;

		private const float ALPHA_OUT = 0.66f;

		private const float ALPHA_OUT_DISABLED = 0.25f;

		private static readonly Color COLOR_OUT = new Color(1f, 1f, 1f, 0.66f);

		private static readonly Color COLOR_HOVER = new Color(1f, 1f, 1f, 1f);

		private static readonly Color COLOR_DISABLED = new Color(1f, 1f, 1f, 0.25f);

		private static GameObject _squareButtonPrefab = null;

		public static void SetCoolButtonEnabled(this CM_Item button, bool enabled)
		{
			//IL_003f: 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_0054: 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)
			if (!((Object)(object)button == (Object)null))
			{
				button.m_spriteAlphaOut = (enabled ? 0.66f : 0.25f);
				button.m_spriteAlphaOver = (enabled ? 1f : 0.25f);
				button.m_spriteColorOut = (enabled ? COLOR_OUT : COLOR_DISABLED);
				button.m_spriteColorOver = (enabled ? COLOR_HOVER : COLOR_DISABLED);
				button.OnHoverOut();
				((Behaviour)button.m_collider).enabled = enabled;
			}
		}

		internal static void Setup(CM_PageLoadout pageLoadout)
		{
			if (!((Object)(object)_squareButtonPrefab != (Object)null))
			{
				_squareButtonPrefab = CreateButtonPrefab(pageLoadout);
			}
		}

		public static CM_Item InstantiateSquareButton(Transform parent, Vector3 position, bool hideText = false, bool displayArrow = false, bool flipArrow = false)
		{
			//IL_001e: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(_squareButtonPrefab, parent);
			val.gameObject.SetActive(true);
			val.transform.localPosition = position;
			CM_Item component = val.GetComponent<CM_Item>();
			if (hideText)
			{
				((Component)val.transform.Find("MainText")).gameObject.SetActive(false);
			}
			Transform val2 = val.transform.Find("Arrow");
			((Component)val2).gameObject.SetActive(displayArrow);
			if (flipArrow)
			{
				val2.localRotation = Quaternion.Euler(0f, 0f, -90f);
			}
			component.m_hoverSpriteArray = Il2CppReferenceArray<SpriteRenderer>.op_Implicit(((IEnumerable<SpriteRenderer>)val.gameObject.GetComponentsInChildren<SpriteRenderer>(true)).ToArray());
			foreach (SpriteRenderer item in (Il2CppArrayBase<SpriteRenderer>)(object)component.m_hoverSpriteArray)
			{
				item.color = new Color(1f, 1f, 1f, 0.66f);
			}
			component.m_spriteAlphaOver = 1f;
			component.m_spriteAlphaOut = 0.66f;
			component.m_alphaSpriteOnHover = true;
			component.m_onBtnPress = new UnityEvent();
			((RectTransformComp)component).Setup();
			return component;
		}

		private static GameObject CreateButtonPrefab(CM_PageLoadout pageLoadout)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			CM_Item component = Object.Instantiate<GameObject>(pageLoadout.m_readyButtonPrefab).GetComponent<CM_Item>();
			GameObject gameObject = ((Component)component).gameObject;
			Transform transform = gameObject.transform;
			Object.Destroy((Object)(object)component);
			component = gameObject.AddComponent<CM_Item>();
			Object.Destroy((Object)(object)((Component)transform.Find("PressAndHold")).gameObject);
			Object.Destroy((Object)(object)((Component)transform.Find("ProgressFillBase")).gameObject);
			Object.Destroy((Object)(object)((Component)transform.Find("ProgressFill")).gameObject);
			Object.Destroy((Object)(object)((Component)transform.Find("Progress")).gameObject);
			transform.Find("MainText").localPosition = new Vector3(-20f, -18f, 0f);
			component.SetText("<color=white>P1</color>");
			Transform obj = transform.Find("Arrow");
			obj.localPosition = new Vector3(0f, -40f, 0f);
			obj.localScale = new Vector3(0.3f, 0.3f, 1f);
			Transform val = transform.Find("Box");
			val.localPosition = new Vector3(0f, -40f, 0f);
			for (int i = 0; i < val.childCount; i++)
			{
				Transform child = val.GetChild(i);
				switch (((Object)child).name)
				{
				case "StretchLineT":
					child.localScale = new Vector3(0.22f, 4f, 1f);
					child.localPosition = new Vector3(-45f, 45f, 0f);
					break;
				case "StretchLineB":
					child.localScale = new Vector3(0.22f, 4f, 1f);
					child.localPosition = new Vector3(-45f, -45f, 0f);
					break;
				case "StretchLineR":
					child.localPosition = new Vector3(45f, 45f, 0f);
					break;
				case "StretchLineL":
					child.localScale = new Vector3(0.5f, 1f, 1f);
					child.localPosition = new Vector3(-45f, 45f, 0f);
					break;
				}
			}
			BoxCollider2D component2 = ((Component)component).GetComponent<BoxCollider2D>();
			component2.size = new Vector2(80f, 80f);
			((Collider2D)component2).offset = new Vector2(0f, -40f);
			((Object)component).name = "LobbyExpander_SwitchLobbyButton";
			Object.DontDestroyOnLoad((Object)(object)gameObject);
			((Object)gameObject).hideFlags = (HideFlags)61;
			gameObject.SetActive(false);
			return gameObject;
		}
	}
	public static class HarmonyControlFlow
	{
		public const bool DontExecute = false;

		public const bool Execute = true;
	}
	internal static class L
	{
		private static readonly ManualLogSource Logger;

		static L()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			Logger = new ManualLogSource("GTFO.LobbyExpansion");
			Logger.Sources.Add((ILogSource)(object)Logger);
		}

		internal static void Assert(bool condition, object data)
		{
			if (!condition)
			{
				string text = "ASSERTION FAILED: " + Format(data);
				Fatal(text);
				throw new ApplicationException(text);
			}
		}

		[Conditional("DEBUG")]
		internal static void DebugWarning(object data)
		{
			Warning("-------------------------------------------");
			Warning("-------------- DEBUG WARNING --------------");
			Warning(Format(data));
			Warning("-------------------------------------------");
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data)
		{
			Logger.LogDebug((object)Format(data));
		}

		internal static void Info(object data)
		{
			Logger.LogMessage((object)Format(data));
		}

		[Conditional("DEBUG")]
		internal static void Verbose(object data)
		{
			Logger.LogDebug((object)Format(data));
		}

		internal static void Error(object data)
		{
			Logger.LogError((object)Format(data));
		}

		internal static void Fatal(object data)
		{
			Logger.LogFatal((object)Format(data));
		}

		internal static void Warning(object data)
		{
			Logger.LogWarning((object)Format(data));
		}

		[Conditional("DEBUG")]
		internal static void LogExecutingMethod(string? parameterInfo = "")
		{
			MethodBase method = new StackFrame(1, needFileInfo: false).GetMethod();
			if (method == null)
			{
				Error("COULD NOT LOG EXECUTING METHOD. THIS SHOULD NOT HAPPEN.");
				return;
			}
			_ = method.DeclaringType?.FullName;
			_ = method.Name;
			if (!string.IsNullOrWhiteSpace(parameterInfo))
			{
				_ = " (" + parameterInfo + ")";
			}
		}

		private static string Format(object msg)
		{
			return msg.ToString() ?? "";
		}
	}
	public class LobbyExpansionPlayerCount
	{
		public byte MaxPlayers { get; set; } = 8;

	}
	public class LobbyExpansionConfig
	{
		public Dictionary<int, SlotPermission>? SlotPermissions { get; set; } = new Dictionary<int, SlotPermission>();


		public List<string>? CustomExtraBotNames { get; set; } = new List<string>();

	}
	public class Pagination
	{
		public int PageIndex { get; set; }

		public event Action? OnPageChanged;

		public bool CanPageUp()
		{
			int num = (int)Math.Ceiling((double)(int)PluginConfig.MaxPlayers / 4.0) - 1;
			return PageIndex < num;
		}

		public bool PageUp()
		{
			if (CanPageUp())
			{
				PageIndex++;
				this.OnPageChanged?.Invoke();
				return true;
			}
			return false;
		}

		public bool CanPageDown()
		{
			return PageIndex > 0;
		}

		public bool PageDown()
		{
			if (CanPageDown())
			{
				PageIndex--;
				this.OnPageChanged?.Invoke();
				return true;
			}
			return false;
		}

		public static int GetLocalPlayerPageIndexFromPillar()
		{
			foreach (CM_PlayerLobbyBar item in (Il2CppArrayBase<CM_PlayerLobbyBar>)(object)CM_PageLoadout.Current.m_playerLobbyBars)
			{
				if (item.m_player.IsLocal)
				{
					return GetPageFromSlotIndex(item.PlayerSlotIndex);
				}
			}
			return 0;
		}

		public static int GetLocalPlayerPageFromSlotIndex()
		{
			return GetPageFromSlotIndex(SNet.LocalPlayer.PlayerSlot.index);
		}

		public static int GetPageFromSlotIndex(int slotIndex)
		{
			return (int)Math.Floor((float)slotIndex / 4f);
		}
	}
	public class PatchingException : Exception
	{
		public PatchingException(string? message)
			: base(message)
		{
		}

		public PatchingException(string? message, Exception? innerException)
			: base(message, innerException)
		{
		}
	}
	[BepInPlugin("GTFO.LobbyExpansion", "GTFO.LobbyExpansion", "1.1.0")]
	public class Plugin : BasePlugin
	{
		private Harmony _harmony;

		public override void Load()
		{
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			try
			{
				PluginConfig.Load();
			}
			catch (Exception ex)
			{
				L.Error("Failed to load plugin config?!");
				L.Error(ex.GetType().Name + ": " + ex.Message);
				L.Warning("StackTrace:\n" + ex.StackTrace);
			}
			try
			{
				HashSet<Type> hashSet = new HashSet<Type>();
				foreach (ManualPatch item in new List<ManualPatch>
				{
					new CM_PageExpeditionSuccessManualPatch(),
					new CM_PageLoadoutManualPatch(),
					new CM_PageMapManualPatch(),
					new CM_PlayerLobbyBarManualPatch(),
					new DiscordManagerManualPatch(),
					new GuiManagerManualPatch(),
					new PLOC_InElevatorManualPatch(),
					new PlayerAgentManualPatch(),
					new PlayerBotAIDataManualPatch(),
					new PlayerCoverageDataSet_NodeManualPatch(),
					new PlayerCoverageDataSet_PortalManualPatch(),
					new PlayerManagerManualPatch(),
					new PlayerSessionStatusManagerManualPatch(),
					new PlayerVoiceManagerManualPatch(),
					new SNet_PlayerSlotManagerManualPatch(),
					new SNet_SyncManagerManualPatch(),
					new CM_PageLoadoutDisplayClassManualPatch()
				})
				{
					Type type = item.GetType();
					if (hashSet.Contains(type))
					{
						string obj = $"The same patch {type} is being applied twice. Fix this.";
						L.Fatal(obj);
						throw new PatchingException(obj);
					}
					item.Apply();
					hashSet.Add(type);
				}
			}
			catch (Exception data)
			{
				L.Fatal("An error occurred while applying manual patches:");
				L.Fatal(data);
				return;
			}
			try
			{
				_harmony = new Harmony("GTFO.LobbyExpansion");
				_harmony.PatchAll();
			}
			catch (Exception data2)
			{
				L.Fatal("An error occurred while applying patches:");
				L.Fatal(data2);
				return;
			}
			L.Info("Loaded plugin GTFO.LobbyExpansion.");
		}
	}
	public static class PluginConfig
	{
		public const byte DEFAULT_MAX_PLAYERS = 8;

		private const string CONFIG_FILE_NAME = "LobbyExpansionConfig.json";

		private const string USER_CONFIG_FILE_NAME = "LobbyExpansionConfig_UserData.json";

		private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
		{
			WriteIndented = true
		};

		private static readonly string _configPath = Path.Combine(Paths.ConfigPath, "LobbyExpansionConfig.json");

		private static readonly string _configPathUserData = Path.Combine(Paths.ConfigPath, "LobbyExpansionConfig_UserData.json");

		internal static byte MaxPlayers = 8;

		private static LobbyExpansionPlayerCount _configPlayerCount = new LobbyExpansionPlayerCount();

		private static LobbyExpansionConfig _configUserData = new LobbyExpansionConfig();

		internal static void Load()
		{
			LoadCustomPlayerCount();
			if (!File.Exists(_configPathUserData))
			{
				SaveUserData();
			}
			_configUserData = JsonSerializer.Deserialize<LobbyExpansionConfig>(File.ReadAllText(_configPathUserData), _serializerOptions) ?? new LobbyExpansionConfig();
			LobbyExpansionConfig configUserData = _configUserData;
			if (configUserData.SlotPermissions == null)
			{
				Dictionary<int, SlotPermission> dictionary2 = (configUserData.SlotPermissions = new Dictionary<int, SlotPermission>());
			}
			configUserData = _configUserData;
			if (configUserData.CustomExtraBotNames == null)
			{
				List<string> list2 = (configUserData.CustomExtraBotNames = new List<string>());
			}
		}

		private static void LoadCustomPlayerCount()
		{
			if (File.Exists(_configPath))
			{
				_configPlayerCount = JsonSerializer.Deserialize<LobbyExpansionPlayerCount>(File.ReadAllText(_configPath), _serializerOptions) ?? new LobbyExpansionPlayerCount();
				if (_configPlayerCount.MaxPlayers < 4)
				{
					L.Error("ConfigFile: MaxPlayers must be greater or equal to '4'!");
					MaxPlayers = 8;
					return;
				}
				L.Info($"Loaded custom player count from config file: {MaxPlayers} (default) -> {_configPlayerCount.MaxPlayers} (config)");
				MaxPlayers = _configPlayerCount.MaxPlayers;
			}
		}

		private static void SaveUserData()
		{
			string contents = JsonSerializer.Serialize(_configUserData, _serializerOptions);
			File.WriteAllText(_configPathUserData, contents);
		}

		public static SlotPermission GetExtraSlotPermission(int slotIndex)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return _configUserData.SlotPermissions.GetValueOrDefault(slotIndex, (SlotPermission)4);
		}

		public static void SetExtraLobbySlotPermissions(int slotIndexMinusOne, SlotPermission permission)
		{
			//IL_0030: 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)
			int num = slotIndexMinusOne + 1;
			L.Info($"SetExtraLobbySlotPermissions called: slotIndex:{num}, SlotPermission:{permission}");
			_configUserData.SlotPermissions[num] = permission;
			SaveUserData();
		}

		public static string GetExtraSlotNickname(int characterIndex)
		{
			int num = characterIndex - 4;
			if (_configUserData.CustomExtraBotNames.Count > 0 && num < _configUserData.CustomExtraBotNames.Count)
			{
				string text = _configUserData.CustomExtraBotNames[num];
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text;
				}
			}
			return characterIndex switch
			{
				4 => "Schaeffer", 
				5 => "North", 
				6 => "Henriksson", 
				7 => "Maddox", 
				_ => $"Prisoner{characterIndex}", 
			};
		}
	}
	internal static class PluginInfo
	{
		internal const string Guid = "GTFO.LobbyExpansion";

		internal const string Name = "GTFO.LobbyExpansion";

		internal const string Version = "1.1.0";
	}
}
namespace GTFO.LobbyExpansion.Util
{
	public static class CoroutineHelpers
	{
		public static IEnumerator NextFrame(Action action)
		{
			yield return null;
			action?.Invoke();
		}
	}
	public abstract class ManualPatch
	{
		protected record Patch
		{
			public string Method { get; init; } = "";


			public string Description { get; init; } = "";


			public string Pattern { get; init; } = "";


			public int Offset { get; init; }

			public byte[] Bytes { get; init; } = Array.Empty<byte>();


			public long? ScanSize { get; init; }

			public Type[]? ParameterTypes { get; init; } = Array.Empty<Type>();

		}

		private static readonly HashSet<IntPtr> PatchedAddresses = new HashSet<IntPtr>();

		protected const byte NOP = 144;

		protected List<Patch> Patches { get; } = new List<Patch>();


		protected abstract Type TargetType { get; }

		public void Apply()
		{
			SetupPatches();
			foreach (Patch patch in Patches)
			{
				Type[] parameterTypes = patch.ParameterTypes ?? Array.Empty<Type>();
				string method = patch.Method;
				bool flag = ((method == ".ctor" || method == "ctor") ? true : false);
				nint num = Memory.FindSignatureInIl2CppMethod(flag ? Memory.GetIl2CppConstructorAddress(TargetType, parameterTypes) : Memory.GetIl2CppMethodAddress(TargetType, patch.Method, parameterTypes), patch.Pattern, patch.ScanSize);
				if (num == 0)
				{
					throw new PatchingException("Could not find pattern for patch \"" + patch.Description + "\".");
				}
				nint num2 = num + patch.Offset;
				if (PatchedAddresses.Contains(num2))
				{
					string text = "Patching the same address " + ((IntPtr)num2).ToString("X") + "! Something is wrong!";
					L.Fatal(text);
					throw new PatchingException(text);
				}
				Memory.PatchMemory(num2, patch.Bytes);
				PatchedAddresses.Add(num2);
			}
		}

		protected abstract void SetupPatches();

		protected static byte[] GenerateNop(int count)
		{
			if (count <= 0)
			{
				throw new ArgumentException("Count must be greater than 0.", "count");
			}
			return Enumerable.Repeat((byte)144, count).ToArray();
		}
	}
	public static class Memory
	{
		private record Signature(byte[] Bytes, char[] Mask);

		private const long DefaultBlockScanSize = 3000L;

		public static nint GetIl2CppConstructorAddress(Type type, params Type[] parameterTypes)
		{
			ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, parameterTypes);
			if (constructor == null)
			{
				IEnumerable<string> value = parameterTypes.Select((Type x) => x.FullName?.ToString() ?? "null");
				throw new MissingMethodException($"Could not find constructor for {type.FullName} with {parameterTypes.Length} parameters ({value}).");
			}
			return GetIl2CppMethodAddress(type, constructor);
		}

		public static nint GetIl2CppConstructorAddress<T>(params Type[] parameterTypes) where T : Il2CppObjectBase
		{
			return GetIl2CppConstructorAddress(typeof(T), parameterTypes);
		}

		public static nint GetIl2CppMethodAddress(Type type, string methodName)
		{
			return GetIl2CppMethodAddress(type, methodName, Array.Empty<Type>());
		}

		public static nint GetIl2CppMethodAddress(Type type, string methodName, Type[] parameterTypes)
		{
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				string value = "";
				if (parameterTypes.Length != 0)
				{
					value = $" with {parameterTypes.Length} parameters (${string.Join(", ", parameterTypes.Select((Type x) => x.FullName?.ToString() ?? x.Name))})";
				}
				throw new MissingMethodException($"Could not find method {methodName} in type {type.FullName}{value}.");
			}
			return GetIl2CppMethodAddress(type, method);
		}

		public static nint GetIl2CppMethodAddress<T>(string methodName) where T : Il2CppObjectBase
		{
			return GetIl2CppMethodAddress<T>(methodName, Array.Empty<Type>());
		}

		public static nint GetIl2CppMethodAddress<T>(string methodName, Type[] parameterTypes) where T : Il2CppObjectBase
		{
			return GetIl2CppMethodAddress(typeof(T), methodName, parameterTypes);
		}

		public unsafe static nint GetIl2CppMethodAddress(Type type, MethodBase methodBase)
		{
			FieldInfo il2CppMethodInfoPointerFieldForGeneratedMethod = Il2CppInteropUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(methodBase);
			if (il2CppMethodInfoPointerFieldForGeneratedMethod == null)
			{
				throw new MissingFieldException($"Could not find IL2CPP method info pointer field for method {methodBase} of {type.FullName ?? type.Name}.");
			}
			return *(nint*)(void*)(IntPtr)(il2CppMethodInfoPointerFieldForGeneratedMethod.GetValue(null) ?? throw new NullReferenceException($"Method info pointer field for method {methodBase} of {type.FullName ?? type.Name} was null."));
		}

		public static nint GetIl2CppMethodAddress<T>(MethodBase methodBase) where T : Il2CppObjectBase
		{
			return GetIl2CppMethodAddress(typeof(T), methodBase);
		}

		public static nint FindSignatureInIl2CppMethod(nint methodPointer, string signature, long? blockSize)
		{
			Signature signature2 = ConvertAobToSignature(signature);
			if (signature2 == null)
			{
				throw new ArgumentException("signature was an invalid signature.");
			}
			return FindSignatureInBlock(methodPointer, blockSize.GetValueOrDefault(3000L), signature2.Bytes, signature2.Mask);
		}

		public static nint FindSignatureInIl2CppMethod<T>(string methodName, string signature, long blockSize = 3000L) where T : Il2CppObjectBase
		{
			return FindSignatureInIl2CppMethod(GetIl2CppMethodAddress<T>(methodName), signature, blockSize);
		}

		public static void PatchMemory(IntPtr address, byte[] bytes)
		{
			if (address == IntPtr.Zero)
			{
				throw new ArgumentException("address cannot be zero.");
			}
			if (!Win32.VirtualProtect(address, new IntPtr(bytes.Length), Win32.MemoryProtection.ExecuteReadWrite, out var lpflOldProtect))
			{
				throw new Exception($"VirtualProtect failed for address {address}.");
			}
			bool flag = false;
			try
			{
				for (int i = 0; i < bytes.Length; i++)
				{
					Marshal.WriteByte(address, i, bytes[i]);
				}
			}
			catch (Exception value)
			{
				Console.WriteLine(value);
				throw;
			}
			finally
			{
				try
				{
					flag = Win32.VirtualProtect(address, new IntPtr(bytes.Length), lpflOldProtect, out var _);
				}
				catch
				{
					L.Error($"VirtualProtect failed to restore protection for address {address}.");
				}
			}
			if (!flag)
			{
				throw new Exception($"VirtualProtect failed to restore protection for address {address}.");
			}
		}

		private unsafe static nint FindSignatureInBlock(nint block, long blockSize, byte[] pattern, char[] mask)
		{
			for (long num = 0L; num < blockSize; num++)
			{
				bool flag = true;
				for (uint num2 = 0u; num2 < mask.Length; num2++)
				{
					if (*(byte*)(num + block + num2) != pattern[num2] && mask[num2] != '?')
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return (nint)(num + block);
				}
			}
			return 0;
		}

		private static Signature? ConvertAobToSignature(string signature)
		{
			if (string.IsNullOrWhiteSpace(signature))
			{
				return null;
			}
			string[] array = signature.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
			if (array.Length == 0)
			{
				return null;
			}
			byte[] array2 = new byte[array.Length];
			char[] array3 = new char[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				if ((text == "?" || text == "??") ? true : false)
				{
					array2[i] = 0;
					array3[i] = '?';
				}
				else
				{
					array2[i] = byte.Parse(text, NumberStyles.HexNumber);
					array3[i] = 'x';
				}
			}
			return new Signature(array2, array3);
		}
	}
	public static class Win32
	{
		[Flags]
		public enum MemoryProtection : uint
		{
			NoAccess = 1u,
			ReadOnly = 2u,
			ReadWrite = 4u,
			WriteCopy = 8u,
			Execute = 0x10u,
			ExecuteRead = 0x20u,
			ExecuteReadWrite = 0x40u,
			ExecuteWriteCopy = 0x80u,
			GuardModifierflag = 0x100u,
			NoCacheModifierflag = 0x200u,
			WriteCombineModifierflag = 0x400u
		}

		[DllImport("kernel32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool VirtualProtect(IntPtr lpAddress, IntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect);
	}
}
namespace GTFO.LobbyExpansion.Patches.Manual
{
	public class CM_PageExpeditionSuccessManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(CM_PageExpeditionSuccess);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "Setup",
				Description = "Adjust hardcoded m_playerReports size in Setup.",
				Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 4C 8D BE F0 01 00 00",
				Offset = 1,
				Bytes = new byte[1] { PluginConfig.MaxPlayers }
			}));
		}
	}
	public class CM_PageLoadoutDisplayClassManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(__c__DisplayClass38_1);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "_ShowPermissionWindow_b__1",
				Description = "NOP out Il2Cpp check and assignment of CellSettingsManager.SettingsData.Player.LobbySlotPermissions[num] = this.permission;",
				Pattern = "48 85 C9 74 5C 3B 71 18 73 7D 48 63 C6 89 54 81 20",
				Offset = 0,
				Bytes = ManualPatch.GenerateNop(17)
			}));
		}
	}
	public class CM_PageLoadoutManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(CM_PageLoadout);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "Setup",
				Description = $"Adjust CM_PageLoadout Setup m_playerLobbyBars size from 4 -> {PluginConfig.MaxPlayers}.",
				Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8B D0 48 89 87 08 02 00 00",
				Offset = 1,
				Bytes = new byte[1] { PluginConfig.MaxPlayers }
			}));
		}
	}
	public class CM_PageMapManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(CM_PageMap);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[13]
			{
				new Patch
				{
					Method = "TryGetInventoryWithSlotIndex",
					Description = "Remove CM_PageMap::TryGetInventoryWithSlotIndex slotIndex > 3",
					Pattern = "83 FF 03 77 60",
					Offset = 2,
					Bytes = new byte[1] { (byte)(PluginConfig.MaxPlayers - 1) }
				},
				new Patch
				{
					Method = "Setup",
					Description = "Adjust CM_PageMap::Setup() m_inventory = new PUI_Inventory[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 4C 8D B7 38 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() m_syncedPlayers = new CM_MapPlayerGUIItem[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 49 8D AF 50 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() m_syncedCursors = new CM_Cursor[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 4D 8D B7 58 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() m_drawPixelBufferIndex = new int[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 49 8D 8F 80 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() m_drawPixelBuffer = new CM_MapDrawPixel[4][] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8B D0 49 89 87 78 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() m_lastDrawingPos = new Vector2[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 49 8D 8F 68 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "CreatePlayerIcons",
					Description = "Adjust CM_PageMap::CreatePlayerIcons() for (int i = 0; i < 4; i++) to new max players.",
					Pattern = "83 FE 04 0F 8C A9 FC FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "UpdatePlayerData",
					Description = "Adjust CM_PageMap::UpdatePlayerData() for (int i = 0; i < 4; i++) to new max players.",
					Pattern = "83 FB 04 0F 8C 21 FF FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "UpdateSyncedCursorVisibility",
					Description = "Adjust CM_PageMap::UpdateSyncedCursorVisibility() for (int i = 0; i < 4; i++) to new max players.",
					Pattern = "83 FB 04 0F 8C 61 FF FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "Update",
					Description = "Adjust CM_PageMap::UpdateSyncedCursorVisibility() (Inlined into Update()!) for (int i = 0; i < 4; i++) to new max players.",
					Pattern = "83 FB 04 0F 8C 55 FF FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "SetPageActive",
					Description = "Adjust CM_PageMap::SetPageActive() m_playerIsDrawing = new bool[4] to new max players.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 8B 60 02 00 00",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "OnEnable",
					Description = "Adjust CM_PageMap::OnEnable() for (int i = 0; i < 4; i++) to new max players.",
					Pattern = "83 FE 04 7C 94",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class CM_PlayerLobbyBarManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(CM_PlayerLobbyBar);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "UpdatePlayer",
				Description = "Adjust hardcoded limit of 4 in CM_PlayerLobbyBar::UpdatePlayer to new max players.",
				Pattern = "83 F8 04 0F 8D F0 00 00 00",
				Offset = 2,
				Bytes = new byte[1] { PluginConfig.MaxPlayers }
			}));
		}
	}
	public class DiscordManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(DiscordManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "GetMaxLobbySize",
				Description = "Adjust DiscordManager::GetMaxLobbySize hardcoded iteration to new max players.",
				Pattern = "BF 04 00 00 00 33 DB",
				Offset = 1,
				Bytes = new byte[1] { PluginConfig.MaxPlayers }
			}));
		}
	}
	public class GuiManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(GuiManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "Setup",
				Description = "Adjust GuiManager::Setup() m_playerPings = new SyncedNavMarkerWrapper[4] to new max players.",
				Pattern = "BA 04 00 00 00 4C 8B E8",
				Offset = 1,
				Bytes = new byte[1] { PluginConfig.MaxPlayers },
				ScanSize = 7500L
			}));
		}
	}
	public class PlayerAgentManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerAgent);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[2]
			{
				new Patch
				{
					Method = "Setup",
					Description = "Remove characterID limit in PlayerAgent::Setup",
					Pattern = "0F 87 12 10 00 00",
					Offset = 0,
					Bytes = ManualPatch.GenerateNop(6)
				},
				new Patch
				{
					Method = "Setup",
					Description = "Remove characterID >= m_modelsForSync length in PlayerAgent::Setup since m_modelsForSync isn't used anyway",
					Pattern = "44 3B 70 18 0F 8D F8 0F 00 00",
					Offset = 4,
					Bytes = ManualPatch.GenerateNop(6)
				}
			}));
		}
	}
	public class PlayerCoverageDataSet_NodeManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerCoverageDataSet_Node);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[4]
			{
				new Patch
				{
					Method = ".ctor",
					Description = "Patch PlayerCoverageDataSet_Node constructor and PlayerCoverageDataSet_Portal$$ constructor (#1)",
					Pattern = "FF C6 83 FE 04 7C 8D 48 8B 5C 24 30",
					Offset = 4,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = ".ctor",
					Description = $"Patch PlayerCoverageDataSet_Node constructor m_coverageDatas array size from 4 -> {PluginConfig.MaxPlayers}.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 4C 8D 73 10 48 8B D0 49 8B CE 49 89 06 E8 ?? ?? ?? ?? 33 D2",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "GetNodeDistanceToClosestPlayer",
					Description = "Adjust GetNodeDistanceToClosestPlayer hardcoded iteration of 4.",
					Pattern = "83 F9 04 7C CC",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "GetNodeDistanceToClosestPlayer_Unblocked",
					Description = "Adjust GetNodeDistanceToClosestPlayer_Unblocked hardcoded iteration of 4.",
					Pattern = "83 FB 04 0F 8C 5B FF FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class PlayerCoverageDataSet_PortalManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerCoverageDataSet_Portal);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[2]
			{
				new Patch
				{
					Method = ".ctor",
					ParameterTypes = new Type[1] { typeof(AIG_CoursePortal) },
					Description = "Patch PlayerCoverageDataSet_Portal constructor (#1) for loop",
					Pattern = "FF C6 83 FE 04 7C 8D 48 8B 5C 24 30",
					Offset = 4,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = ".ctor",
					ParameterTypes = new Type[1] { typeof(AIG_CoursePortal) },
					Description = $"Patch PlayerCoverageDataSet_Portal constructor m_coverageDatas array size from 4 -> {PluginConfig.MaxPlayers}.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 4C 8D 73 10 48 8B D0 49 8B CE 49 89 06 E8 ?? ?? ?? ?? 33 F6",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class PlayerManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[4]
			{
				new Patch
				{
					Method = "SpawnBot",
					Description = "Remove SpawnBot hardcoded limit of 4.",
					Pattern = "83 78 18 04 0F 84 C0 03 00 00",
					Offset = 4,
					Bytes = ManualPatch.GenerateNop(6)
				},
				new Patch
				{
					Method = ".ctor",
					Description = "Set constructor m_botSlot size to new max player limit.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4E 70",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = ".ctor",
					Description = "Patch inlined version of the creation of PositionReservations in PlayerManager constructor.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 20 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 28 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 30 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 38 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 33 D2 48 8B CF E8",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = ".ctor",
					Description = "Patch inlined version of the creation of ObjectReservations in PlayerManager constructor.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 28 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 30 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 38 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 33 D2 48 8B CF E8",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class PlayerBotAIDataManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerBotAIData);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[2]
			{
				new Patch
				{
					Method = ".ctor",
					Description = "Set PlayerBotAIData constructor PositionReservations size to new max player limit.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 20 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 28 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 30 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 38 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 33 D2 48 8B CF 48 8B 5C 24 30",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = ".ctor",
					Description = "Set PlayerBotAIData constructor ObjectReservations size to new max player limit.",
					Pattern = "BA 04 00 00 00 E8 ?? ?? ?? ?? 48 8D 4F 28 48 8B D0 48 89 01 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 30 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 8D 4F 38 48 8B D3 48 89 19 E8 ?? ?? ?? ?? 33 D2 48 8B CF 48 8B 5C 24 30",
					Offset = 1,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class PlayerSessionStatusManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerSessionStatusManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "OnPlayerStateCapture",
				Description = "Adjust PlayerSessionStatusManager::OnPlayerStateCapture() bool flag2 = characterIndex > -1 && characterIndex < 4; to new max players.",
				Pattern = "83 F8 04 0F 9C C3",
				Offset = 2,
				Bytes = new byte[1] { PluginConfig.MaxPlayers }
			}));
		}
	}
	public class PlayerVoiceManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PlayerVoiceManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "RegisterPlayerVoice",
				Description = "Patch PlayerVoiceManager < 3",
				Pattern = "83 FE 03 76 67",
				Offset = 2,
				Bytes = new byte[1] { (byte)(PluginConfig.MaxPlayers - 1) }
			}));
		}
	}
	public class PLOC_InElevatorManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(PLOC_InElevator);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "CommonEnter",
				Description = "PLOC_InElevator::CommonEnter PLOCStateReferenceID > 3",
				Pattern = "83 B8 A0 00 00 00 03",
				Offset = 6,
				Bytes = new byte[1] { (byte)(PluginConfig.MaxPlayers - 1) }
			}));
		}
	}
	public class SNet_PlayerSlotManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(SNet_PlayerSlotManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlyArray<Patch>(new Patch[7]
			{
				new Patch
				{
					Method = "Internal_ManageSlot",
					Description = "Adjust Internal_ManageSlot hardcoded iteration of 4.",
					Pattern = "83 FF 04 0F 8C D1 FE FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "OnResetSession",
					Description = "Adjust OnResetSession hardcoded iteration of 4.",
					Pattern = "83 FB 04 7C 9E",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "OnValidateMasterData",
					Description = "Adjust OnValidateMasterData hardcoded iteration of 4.",
					Pattern = "83 FF 04 0F 8C 68 FE FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "HasFreeBotSlot",
					Description = "Adjust HasFreeBotSlot hardcoded iteration of 4.",
					Pattern = "83 FB 04 7C 87",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "HasFreeHumanSlot",
					Description = "Adjust HasFreeHumanSlot hardcoded iteration of 4.",
					Pattern = "83 FB 04 0F 8C 38 FF FF FF",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "SetAllPlayerSlotPermissions",
					Description = "Adjust SetAllPlayerSlotPermissions hardcoded iteration of 4.",
					Pattern = "83 FB 04 7C C7",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				},
				new Patch
				{
					Method = "AreSlotPermissionsSet",
					Description = "Adjust AreSlotPermissionsSet hardcoded iteration of 4.",
					Pattern = "83 F8 04 7C EA",
					Offset = 2,
					Bytes = new byte[1] { PluginConfig.MaxPlayers }
				}
			}));
		}
	}
	public class SNet_SyncManagerManualPatch : ManualPatch
	{
		protected override Type TargetType { get; } = typeof(SNet_SyncManager);


		protected override void SetupPatches()
		{
			base.Patches.AddRange(new <>z__ReadOnlySingleElementList<Patch>(new Patch
			{
				Method = "ValidateIndex",
				Description = "Remove SNet_SyncManager::ValidateIndex character index > 3 check, since we're using higher characterIDs.",
				Pattern = "0F 87 C8 06 00 00",
				Offset = 0,
				Bytes = ManualPatch.GenerateNop(6)
			}));
		}
	}
}
namespace GTFO.LobbyExpansion.Patches.Harmony
{
	[HarmonyPatch(typeof(BoosterImplantManager))]
	public static class BoosterImplantManagerPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake__Postfix(BoosterImplantManager __instance)
		{
			if (((Il2CppArrayBase<PlayerBoosterImplantState>)(object)__instance.m_boosterPlayers).Length < PluginConfig.MaxPlayers)
			{
				__instance.m_boosterPlayers = new Il2CppReferenceArray<PlayerBoosterImplantState>((long)PluginConfig.MaxPlayers);
			}
		}
	}
	[HarmonyPatch(typeof(CM_PageExpeditionSuccess))]
	public static class CM_PageExpeditionSuccessPatch
	{
		private static bool _needPositionUpdate;

		private static DateTime _lastVisibilityUpdate = DateTime.Now;

		private static readonly Pagination _pagination = new Pagination();

		private static CM_Item _buttonPageUp = null;

		private static CM_Item _buttonPageDown = null;

		[HarmonyPatch("OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable__Postfix(CM_PageExpeditionSuccess __instance)
		{
			_pagination.PageIndex = 0;
			UpdateCustomButtons();
			_needPositionUpdate = true;
			UpdateVisiblePlayerReports(__instance);
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update__Postfix(CM_PageExpeditionSuccess __instance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (_needPositionUpdate)
			{
				for (int i = 4; i < ((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)__instance.m_playerReports).Length; i++)
				{
					Transform transform = ((Component)((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)__instance.m_playerReports)[i % 4]).transform;
					((Component)((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)__instance.m_playerReports)[i]).transform.position = transform.position;
					((Component)((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)__instance.m_playerReports)[i]).transform.parent = transform.parent;
				}
				_needPositionUpdate = false;
			}
			if (DateTime.Now > _lastVisibilityUpdate)
			{
				_lastVisibilityUpdate = DateTime.Now + TimeSpan.FromMilliseconds(50.0);
				UpdateVisiblePlayerReports(__instance);
			}
			if (Input.GetKeyDown((KeyCode)281))
			{
				_pagination.PageDown();
			}
			if (Input.GetKeyDown((KeyCode)280))
			{
				_pagination.PageUp();
			}
		}

		private static void UpdateVisiblePlayerReports(CM_PageExpeditionSuccess page)
		{
			if (page.m_playerReports == null)
			{
				return;
			}
			Il2CppReferenceArray<SNet_Slot> playerSlots = SNet.Slots.PlayerSlots;
			int num = _pagination.PageIndex * 4;
			int num2 = Math.Min(num + 4, PluginConfig.MaxPlayers);
			for (int i = 0; i < ((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)page.m_playerReports).Count; i++)
			{
				if (!((Object)(object)((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)page.m_playerReports)[i] == (Object)null))
				{
					bool active = true;
					if (i < num)
					{
						active = false;
					}
					else if (i >= num2)
					{
						active = false;
					}
					else if (i >= ((Il2CppArrayBase<SNet_Slot>)(object)playerSlots).Count || (Object)(object)((Il2CppArrayBase<SNet_Slot>)(object)playerSlots)[i].player == (Object)null)
					{
						active = false;
					}
					((Component)((Il2CppArrayBase<CM_PageSuccess_PrisonerEvaluation>)(object)page.m_playerReports)[i]).gameObject.SetActive(active);
				}
			}
		}

		private static void OnPageChanged()
		{
			UpdateVisiblePlayerReports(MainMenuGuiLayer.Current.PageExpeditionSuccess);
			UpdateCustomButtons();
		}

		private static void UpdateCustomButtons()
		{
			bool enabled = _pagination.CanPageDown();
			bool enabled2 = _pagination.CanPageUp();
			_buttonPageDown.SetCoolButtonEnabled(enabled);
			_buttonPageUp.SetCoolButtonEnabled(enabled2);
		}

		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(CM_PageExpeditionSuccess __instance, MainMenuGuiLayer guiLayer)
		{
			CM_PageExpeditionSuccess __instance2 = __instance;
			_pagination.OnPageChanged += OnPageChanged;
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoroutineHelpers.NextFrame(delegate
			{
				//IL_001f: 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)
				_buttonPageUp = CoolButton.InstantiateSquareButton(((Component)__instance2.m_btnLeaveExpedition).transform, new Vector3(320f, 42f, 0f), hideText: true, displayArrow: true);
				_buttonPageDown = CoolButton.InstantiateSquareButton(((Component)__instance2.m_btnLeaveExpedition).transform, new Vector3(-320f, 42f, 0f), hideText: true, displayArrow: true, flipArrow: true);
				UpdateCustomButtons();
				_buttonPageUp.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageUp();
				});
				_buttonPageDown.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageDown();
				});
			})), (Action)null);
		}
	}
	[HarmonyPatch(typeof(__c__DisplayClass38_1))]
	public class CM_PageLoadoutDisplayClassPatch
	{
		[HarmonyPatch("_ShowPermissionWindow_b__1")]
		public static void Prefix(__c__DisplayClass38_1 __instance)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			for (int i = 0; i < __instance.field_Public___c__DisplayClass38_0_0.playerIndex; i++)
			{
				SNet_Player player = ((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots)[i].player;
				if ((Object)(object)player == (Object)null || !player.IsLocal)
				{
					num++;
				}
			}
			if (num < 3)
			{
				((Il2CppArrayBase<SlotPermission>)(object)CellSettingsManager.SettingsData.Player.LobbySlotPermissions)[num] = __instance.permission;
			}
			else
			{
				PluginConfig.SetExtraLobbySlotPermissions(num, __instance.permission);
			}
		}
	}
	[HarmonyPatch(typeof(CM_PageLoadout))]
	public static class CM_PageLoadoutPatch
	{
		private static CM_Item _centerButton = null;

		private static CM_Item _buttonPageDown = null;

		private static CM_Item _buttonPageUp = null;

		private const string DECOR_TEXT = "//: Lobby Page Switcher";

		private static readonly Pagination _pagination = new Pagination();

		[HarmonyPatch("Setup")]
		[HarmonyPrefix]
		public static bool Setup__Prefix(CM_PageLoadout __instance, MainMenuGuiLayer guiLayer)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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)
			Il2CppReferenceArray<Transform> playerInfoHolders = __instance.m_playerInfoHolders;
			__instance.m_playerInfoHolders = new Il2CppReferenceArray<Transform>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < 4; i++)
			{
				((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[i] = ((Il2CppArrayBase<Transform>)(object)playerInfoHolders)[i];
			}
			GameObject val = GameObject.Find("GUI/CellUI_Camera(Clone)/MainMenuLayer/CM_PageLoadout_CellUI(Clone)/PlayerMovement/PlayerPillars");
			L.Assert((Object)(object)val != (Object)null, "playerPillarsGameObj was null!");
			for (int j = 4; j < PluginConfig.MaxPlayers; j++)
			{
				GameObject val2 = new GameObject($"Player{j + 1}Root");
				Transform val3 = ((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[j % 4];
				val2.transform.position = val3.position;
				val2.transform.localPosition = val3.localPosition;
				val2.transform.localScale = val3.localScale;
				val2.transform.SetParent(val.transform);
				val2.layer = LayerMask.NameToLayer("UI");
				val2.SetActive(true);
				((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[j] = val2.transform;
			}
			return true;
		}

		[HarmonyPatch("ArrangePlayerPillarSpacing")]
		[HarmonyPostfix]
		public static void ArrangePlayerPillarSpacing__Postfix(CM_PageLoadout __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[4]
			{
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[0]).transform.position,
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[1]).transform.position,
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[2]).transform.position,
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[3]).transform.position
			};
			for (int i = 4; i < PluginConfig.MaxPlayers; i++)
			{
				_ = $"Player{i + 1}Root";
				Transform val = ((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[i % 4];
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[i]).transform.position = val.position;
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[i]).transform.localPosition = val.localPosition;
				((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[i]).transform.localScale = val.localScale;
			}
			int num = _pagination.PageIndex * 4;
			int num2 = Math.Min(num + 4, PluginConfig.MaxPlayers);
			for (int j = 0; j < ((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders).Count; j++)
			{
				if (j < num)
				{
					((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[j]).gameObject.transform.position = new Vector3(5000f, 5000f, 5000f);
				}
				else if (j >= num2)
				{
					((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[j]).gameObject.transform.position = new Vector3(5000f, 5000f, 5000f);
				}
				else
				{
					((Component)((Il2CppArrayBase<Transform>)(object)__instance.m_playerInfoHolders)[j]).transform.position = array[j % array.Length];
				}
			}
		}

		public static void UpdatePlayerPillars()
		{
			CM_PageLoadout.Current.ArrangePlayerPillarSpacing();
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update__Postfix(CM_PageLoadout __instance)
		{
			if (Input.GetKeyDown((KeyCode)281) && _pagination.PageDown())
			{
				UpdateCustomButtons();
			}
			if (Input.GetKeyDown((KeyCode)280) && _pagination.PageUp())
			{
				UpdateCustomButtons();
			}
		}

		[HarmonyPatch("ApplyPlayerSlotPermissionsFromSettings")]
		[HarmonyPostfix]
		public static void ApplyPlayerSlotPermissionsFromSettings__Postfix(CM_PageLoadout __instance)
		{
			//IL_000a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			for (int i = 4; i < PluginConfig.MaxPlayers; i++)
			{
				SlotPermission extraSlotPermission = PluginConfig.GetExtraSlotPermission(i);
				if ((Object)(object)((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots)[i].player == (Object)null || !((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots)[i].player.IsLocal)
				{
					flag = SNet.Slots.SetSlotPermission(i, extraSlotPermission) || flag;
				}
				else if (((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots)[i].player.IsLocal)
				{
					flag = SNet.Slots.SetSlotPermission(i, (SlotPermission)4) || flag;
				}
			}
			if (!flag)
			{
				SNet.Core.OnSlotsStatusChanged();
			}
			if (SNet_Events.OnLobbyPermissionsSet != null)
			{
				SNet_Events.OnLobbyPermissionsSet.Invoke();
			}
		}

		[HarmonyPatch("OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable__Postfix()
		{
		}

		private static void UpdateCustomButtons()
		{
			bool enabled = _pagination.CanPageDown();
			bool enabled2 = _pagination.CanPageUp();
			_buttonPageDown.SetCoolButtonEnabled(enabled);
			_buttonPageUp.SetCoolButtonEnabled(enabled2);
			_centerButton.SetText($"<color=white>P{_pagination.PageIndex + 1}</color>");
		}

		private static void OnPageChanged()
		{
			UpdatePlayerPillars();
		}

		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(CM_PageLoadout __instance, MainMenuGuiLayer guiLayer)
		{
			CM_PageLoadout __instance2 = __instance;
			if ((Object)(object)CM_PageLoadout.Current == (Object)null)
			{
				return;
			}
			_pagination.OnPageChanged += OnPageChanged;
			CoolButton.Setup(__instance2);
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoroutineHelpers.NextFrame(delegate
			{
				//IL_0005: 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_0046: 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_0056: 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_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: 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_0115: Unknown result type (might be due to invalid IL or missing references)
				Transform transform = new GameObject("LobbySwitcherHolder").transform;
				transform.SetParent(__instance2.m_readyButtonAlign.parent);
				transform.localPosition = __instance2.m_readyButtonAlign.localPosition + new Vector3(0f, 1150f, 0f);
				transform.localScale = Vector3.one * 0.9f;
				Transform obj = Object.Instantiate<Transform>(__instance2.m_readyButtonAlign.Find("DecorText"), transform);
				((Component)obj).transform.localPosition = new Vector3(100f, 0f, 0f);
				((Component)obj).transform.localScale = Vector3.one;
				((Component)obj).gameObject.SetActive(true);
				((TMP_Text)((Component)obj).GetComponent<TextMeshPro>()).SetText("//: Lobby Page Switcher", true);
				_centerButton = CoolButton.InstantiateSquareButton(transform, Vector3.zero);
				_buttonPageDown = CoolButton.InstantiateSquareButton(transform, new Vector3(-110f, 0f, 0f), hideText: true, displayArrow: true, flipArrow: true);
				_buttonPageUp = CoolButton.InstantiateSquareButton(transform, new Vector3(110f, 0f, 0f), hideText: true, displayArrow: true);
				UpdateCustomButtons();
				_centerButton.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					int localPlayerPageIndexFromPillar = Pagination.GetLocalPlayerPageIndexFromPillar();
					if (_pagination.PageIndex != localPlayerPageIndexFromPillar)
					{
						_pagination.PageIndex = localPlayerPageIndexFromPillar;
						UpdatePlayerPillars();
					}
					UpdateCustomButtons();
				});
				_buttonPageDown.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageDown();
					UpdateCustomButtons();
				});
				_buttonPageUp.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageUp();
					UpdateCustomButtons();
				});
			})), (Action)null);
		}
	}
	[HarmonyPatch(typeof(CM_PageMap))]
	public static class CM_PageMapPatch
	{
		private static readonly Pagination _pagination = new Pagination();

		private static CM_Item _buttonCenter = null;

		private static CM_Item _buttonPageUp = null;

		private static CM_Item _buttonPageDown = null;

		private static void OnPageChanged()
		{
			UpdateCustomButtons();
			UpdateAllPlayerInventories();
		}

		private static void UpdateCustomButtons()
		{
			_buttonPageUp.SetCoolButtonEnabled(_pagination.CanPageUp());
			_buttonPageDown.SetCoolButtonEnabled(_pagination.CanPageDown());
			_buttonCenter.SetText($"<color=white>P{_pagination.PageIndex + 1}</color>");
		}

		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(CM_PageMap __instance)
		{
			CM_PageMap __instance2 = __instance;
			_pagination.OnPageChanged += OnPageChanged;
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoroutineHelpers.NextFrame(delegate
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: 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_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: 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_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: 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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = new GameObject("LobbyExpansion_PageButtonRoot");
				val.transform.SetParent(((Component)__instance2.m_btnGotoObjectives).transform);
				val.transform.localPosition = new Vector3(40f, -200f, 0f);
				val.transform.localScale = Vector3.one * 0.6f;
				_buttonCenter = CoolButton.InstantiateSquareButton(val.transform, Vector3.zero);
				_buttonPageDown = CoolButton.InstantiateSquareButton(val.transform, new Vector3(-40f, 80f, 0f), hideText: true, displayArrow: true);
				((Component)_buttonPageDown).transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
				_buttonPageUp = CoolButton.InstantiateSquareButton(val.transform, new Vector3(-40f, -160f, 0f), hideText: true, displayArrow: true, flipArrow: true);
				((Component)_buttonPageUp).transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
				UpdateCustomButtons();
				_buttonCenter.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					int localPlayerPageFromSlotIndex = Pagination.GetLocalPlayerPageFromSlotIndex();
					if (_pagination.PageIndex != localPlayerPageFromSlotIndex)
					{
						_pagination.PageIndex = localPlayerPageFromSlotIndex;
						UpdateAllPlayerInventories();
					}
					UpdateCustomButtons();
				});
				_buttonPageDown.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageDown();
				});
				_buttonPageUp.OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					_pagination.PageUp();
				});
			})), (Action)null);
		}

		private static void UpdateAllPlayerInventories()
		{
			CM_PageMap current = CM_PageMap.Current;
			int num = 0;
			Enumerator<SNet_Player> enumerator = SNet.Slots.SlottedPlayers.GetEnumerator();
			while (enumerator.MoveNext())
			{
				SNet_Player current2 = enumerator.Current;
				if (current2.IsInSlot)
				{
					current.UpdatePlayerInventory(current2, num);
					num++;
				}
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update__Postfix()
		{
			if (Input.GetKeyDown((KeyCode)281))
			{
				_pagination.PageDown();
			}
			if (Input.GetKeyDown((KeyCode)280))
			{
				_pagination.PageUp();
			}
		}

		[HarmonyPatch("UpdatePlayerInventory")]
		[HarmonyPostfix]
		public static void UpdatePlayerInventory__Postfix(CM_PageMap __instance, SNet_Player player, int count)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			PUI_Inventory val = ((Il2CppArrayBase<PUI_Inventory>)(object)__instance.m_inventory)[player.PlayerSlotIndex()];
			Vector2 position = ((RectTransformComp)val).GetPosition();
			Vector2 position2 = default(Vector2);
			((Vector2)(ref position2))..ctor(position.x, position.y);
			int num = 0;
			for (int num2 = count; num2 > 3; num2 -= 4)
			{
				num++;
			}
			if (_pagination.PageIndex != num)
			{
				position2.x = 5000f;
			}
			position2.y = -150f + (float)(count % 4) * (0f - __instance.m_inventoryOffsetPerPlayer);
			((RectTransformComp)val).SetPosition(position2);
		}
	}
	[HarmonyPatch(typeof(CM_PlayerLobbyBar))]
	public static class CM_PlayerLobbyBarPatch
	{
		[HarmonyPatch("SpawnPlayerModel")]
		[HarmonyPrefix]
		public static bool SpawnPlayerModel__Prefix(CM_PlayerLobbyBar __instance, ref int index)
		{
			if (index > 3)
			{
				int num = index % 4;
				index = num;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CP_PlayerScanner))]
	public static class CP_PlayerScannerPatch
	{
		[HarmonyPatch("StartScan")]
		[HarmonyPrefix]
		public static bool StartScan__Prefix(CP_PlayerScanner __instance)
		{
			if (((Il2CppArrayBase<float>)(object)__instance.m_scanSpeeds).Length < PluginConfig.MaxPlayers)
			{
				Il2CppStructArray<float> scanSpeeds = __instance.m_scanSpeeds;
				__instance.m_scanSpeeds = new Il2CppStructArray<float>((long)PluginConfig.MaxPlayers);
				for (int i = 0; i < PluginConfig.MaxPlayers; i++)
				{
					((Il2CppArrayBase<float>)(object)__instance.m_scanSpeeds)[i] = ((Il2CppArrayBase<float>)(object)scanSpeeds)[Math.Min(i, ((Il2CppArrayBase<float>)(object)scanSpeeds).Length - 1)];
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(DefaultCharacterLayouts))]
	public class DefaultCharacterLayoutsPatch
	{
		[HarmonyPatch("GetDefaultVanityItems")]
		[HarmonyPrefix]
		public static bool GetDefaultVanityItems__Prefix(ref int characterIndex)
		{
			if (characterIndex > 3)
			{
				characterIndex %= 4;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(DiscordManager))]
	public class DiscordManagerPatch
	{
		[HarmonyPatch("GetCharacterNickname")]
		[HarmonyPostfix]
		public static void GetCharacterNickname__Postfix(ref string __result, int characterIndex)
		{
			if (characterIndex > 3)
			{
				__result = PluginConfig.GetExtraSlotNickname(characterIndex);
			}
		}
	}
	[HarmonyPatch(typeof(DramaManager))]
	public static class DramaManagerPatch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix()
		{
			ResetDramaFieldsProperly();
		}

		[HarmonyPatch("OnLevelCleanup")]
		[HarmonyPostfix]
		public static void OnLevelCleanup__Postfix()
		{
			ResetDramaFieldsProperly();
		}

		private static void ResetDramaFieldsProperly()
		{
			DramaManager.SyncedPlayerStates = new Il2CppStructArray<DRAMA_State>((long)PluginConfig.MaxPlayers);
			DramaManager.SyncedPlayerTensions = new Il2CppStructArray<float>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < ((Il2CppArrayBase<DRAMA_State>)(object)DramaManager.SyncedPlayerStates).Length; i++)
			{
				((Il2CppArrayBase<DRAMA_State>)(object)DramaManager.SyncedPlayerStates)[i] = (DRAMA_State)0;
			}
		}
	}
	[HarmonyPatch(typeof(ElevatorCage))]
	public static class ElevatorCagePatch
	{
		[HarmonyPatch("SkipPreReleaseSequence")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool SkipPreReleaseSequence__Prefix(ElevatorCage __instance, CellSoundPlayer sound, ref int playerId)
		{
			if ((Object)(object)((Il2CppArrayBase<ElevatorSeat>)(object)__instance.m_seatsFromShaft)[playerId] == (Object)null)
			{
				L.Warning($"playerId {playerId} has a null seat. Skipping call.");
				return false;
			}
			return true;
		}

		[HarmonyPatch("RegisterSpawnPoints")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool RegisterSpawnPoints__Prefix(ElevatorCage __instance)
		{
			__instance.m_spawnPoints = new Il2CppReferenceArray<PlayerSpawnpoint>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < PluginConfig.MaxPlayers; i++)
			{
				int num = i % 4;
				((Il2CppArrayBase<PlayerSpawnpoint>)(object)__instance.m_spawnPoints)[i] = PlayerManager.RegisterSpawnpoint((PlayerspawnpointType)0, i, ((Il2CppArrayBase<ElevatorSeat>)(object)__instance.m_seatsFromShaft)[num]);
			}
			return false;
		}

		[HarmonyPatch("PlaySeatOpenStraps")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool PlaySeatOpenStraps__Prefix(CellSoundPlayer sound, int playerId, bool isLocal)
		{
			if (playerId > 3)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ElevatorRide))]
	public static class ElevatorRidePatch
	{
		[HarmonyPatch("StartPreReleaseSequence")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool StartPreReleaseSequence__Prefix(Action onDone)
		{
			return true;
		}

		[HarmonyPatch("Cleanup")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool Cleanup__Prefix()
		{
			return true;
		}

		[HarmonyPatch("SpawnShaftSegments")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		public static void SpawnShaftSegments__Postfix(ElevatorRide __instance)
		{
			ElevatorRide __instance2 = __instance;
			ElevatorShaftTop shaftTop = __instance2.m_shaftTop;
			Il2CppReferenceArray<ElevatorSeat> elevatorSeats = shaftTop.m_elevatorSeats;
			shaftTop.m_elevatorSeats = new Il2CppReferenceArray<ElevatorSeat>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < PluginConfig.MaxPlayers; i++)
			{
				int num = i % 4;
				((Il2CppArrayBase<ElevatorSeat>)(object)shaftTop.m_elevatorSeats)[i] = ((Il2CppArrayBase<ElevatorSeat>)(object)elevatorSeats)[num];
			}
			Il2CppReferenceArray<Animator> hSULoadingArmAnims = shaftTop.m_HSULoadingArmAnims;
			shaftTop.m_HSULoadingArmAnims = new Il2CppReferenceArray<Animator>((long)PluginConfig.MaxPlayers);
			for (int j = 0; j < PluginConfig.MaxPlayers; j++)
			{
				int num2 = j % 4;
				((Il2CppArrayBase<Animator>)(object)shaftTop.m_HSULoadingArmAnims)[j] = ((Il2CppArrayBase<Animator>)(object)hSULoadingArmAnims)[num2];
			}
			((MonoBehaviour)__instance2).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoroutineHelpers.NextFrame(delegate
			{
				ElevatorCage elevatorCage = __instance2.m_elevatorCage;
				Il2CppReferenceArray<Transform> hSUAligns = elevatorCage.m_HSUAligns;
				elevatorCage.m_HSUAligns = new Il2CppReferenceArray<Transform>((long)PluginConfig.MaxPlayers);
				for (int k = 0; k < PluginConfig.MaxPlayers; k++)
				{
					int num3 = k % 4;
					((Il2CppArrayBase<Transform>)(object)elevatorCage.m_HSUAligns)[k] = ((Il2CppArrayBase<Transform>)(object)hSUAligns)[num3];
				}
			})));
		}

		[HarmonyPatch("Cleanup")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		public static void Cleanup__Postfix()
		{
			if (ElevatorRide.ElevatorRideInProgress)
			{
				ElevatorRide.ElevatorRideInProgress = false;
				ElevatorRide.Current.m_shaftTop.Cleanup();
			}
		}
	}
	[HarmonyPatch(typeof(ElevatorSeat))]
	public class ElevatorSeatPatch
	{
		private static int _frame;

		[HarmonyPatch("SkipPreReleaseSequence")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		public static void SkipPreReleaseSequence__Postfix(CellSoundPlayer sound)
		{
			CellSoundPlayer sound2 = sound;
			sound2.Stop();
			int frameCount = Time.frameCount;
			if (_frame != frameCount)
			{
				CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoroutineHelpers.NextFrame(delegate
				{
					sound2.Post(EVENTS.PLAY_15_ELEVATOR_RELEASE, true);
				})), (Action)null);
			}
			_frame = frameCount;
		}
	}
	[HarmonyPatch(typeof(EnemyAgent))]
	public class EnemyAgentArenaDimensionPatch
	{
		[HarmonyPatch("GetArenaDimension")]
		[HarmonyPrefix]
		public static void GetArenaDimension__Prefix(ref uint slotIndex)
		{
			slotIndex %= 4u;
		}
	}
	[HarmonyPatch(typeof(GearManager))]
	public static class GearManagerPatch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix()
		{
			BotFavoritesData botFavoritesData = GearManager.BotFavoritesData;
			Il2CppStringArray original = botFavoritesData.LastEquipped_Melee;
			if (Expand(ref original))
			{
				botFavoritesData.LastEquipped_Melee = original;
			}
			Il2CppStringArray original2 = botFavoritesData.LastEquipped_Standard;
			if (Expand(ref original2))
			{
				botFavoritesData.LastEquipped_Standard = original2;
			}
			Il2CppStringArray original3 = botFavoritesData.LastEquipped_Special;
			if (Expand(ref original3))
			{
				botFavoritesData.LastEquipped_Special = original3;
			}
			Il2CppStringArray original4 = botFavoritesData.LastEquipped_Class;
			if (Expand(ref original4))
			{
				botFavoritesData.LastEquipped_Class = original4;
			}
			Il2CppStringArray original5 = botFavoritesData.LastEquipped_HackingTool;
			if (Expand(ref original5))
			{
				botFavoritesData.LastEquipped_HackingTool = original5;
			}
		}

		private static bool Expand(ref Il2CppStringArray original)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (((Il2CppArrayBase<string>)(object)original).Length >= PluginConfig.MaxPlayers)
			{
				return false;
			}
			Il2CppStringArray val = original;
			Il2CppStringArray val2 = new Il2CppStringArray((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < ((Il2CppArrayBase<string>)(object)val2).Length; i++)
			{
				if (i < ((Il2CppArrayBase<string>)(object)val).Length)
				{
					((Il2CppArrayBase<string>)(object)val2)[i] = ((Il2CppArrayBase<string>)(object)val)[i];
				}
				else
				{
					((Il2CppArrayBase<string>)(object)val2)[i] = string.Empty;
				}
			}
			original = val2;
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerAgent))]
	public static class PlayerAgentPatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool PlayerCharacterFilter__Getter__Prefix(PlayerAgent __instance, ref DialogCharFilter __result)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			int characterID = __instance.CharacterID;
			if (characterID > 3)
			{
				int num = characterID % 4;
				__result = (DialogCharFilter)(int)((Il2CppArrayBase<DialogCharFilter>)(object)__instance.m_playerCharacters)[num];
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerCoverageSystem))]
	public static class PlayerCoverageSystemPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake__Postfix()
		{
			if (((Il2CppArrayBase<int>)(object)PlayerCoverageSystem.s_coverageKeys).Length < PluginConfig.MaxPlayers)
			{
				PlayerCoverageSystem.s_coverageKeys = new Il2CppStructArray<int>((long)PluginConfig.MaxPlayers);
			}
		}

		[HarmonyPatch("GetCoverageKey", new Type[] { typeof(int) })]
		[HarmonyPrefix]
		public static bool GetCoverageKey__Prefix(ref int __result, int activeID)
		{
			if (activeID < 0)
			{
				return true;
			}
			if (activeID >= ((Il2CppArrayBase<int>)(object)PlayerCoverageSystem.s_coverageKeys).Length)
			{
				L.Error($"{"activeID"} was greater than the size of s_coverageKeys ({((Il2CppArrayBase<int>)(object)PlayerCoverageSystem.s_coverageKeys).Length}).");
				return true;
			}
			__result = ((Il2CppArrayBase<int>)(object)PlayerCoverageSystem.s_coverageKeys)[activeID];
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerCoverageDataSet_Portal))]
	public static class PlayerCoverageDataSet_PortalPatch
	{
		[HarmonyPatch("SetupData")]
		[HarmonyPostfix]
		public static void SetupData__Postfix(PlayerCoverageDataSet_Portal? __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			L.Assert(__instance != null, "instance was null");
			__instance.m_coverageDatas = new Il2CppReferenceArray<PlayerCoverageData>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < ((Il2CppArrayBase<PlayerCoverageData>)(object)__instance.m_coverageDatas).Length; i++)
			{
				((Il2CppArrayBase<PlayerCoverageData>)(object)__instance.m_coverageDatas)[i] = new PlayerCoverageData();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerDialogManager))]
	public static class PlayerDialogManagerPatch
	{
		[HarmonyPatch("WantToStartDialog")]
		[HarmonyPatch(new Type[]
		{
			typeof(uint),
			typeof(PlayerAgent)
		})]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool WantToStartDialog__Prefix(uint dialogID, PlayerAgent source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerManager))]
	public static class PlayerManagerPatch
	{
		private static readonly Random _random = new Random(690420);

		[HarmonyPatch("GetSpawnPoint")]
		[HarmonyPrefix]
		public static bool GetSpawnPoint__Prefix(PlayerspawnpointType type, ref int referenceID)
		{
			if (referenceID > 3)
			{
				int num = referenceID % 4;
				referenceID = num;
			}
			return true;
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake__Postfix(PlayerManager? __instance)
		{
			L.Assert((Object)(object)__instance != (Object)null, "__instance was null");
			L.Assert(((Il2CppArrayBase<List<PositionReservation>>)(object)__instance.BotAIData.PositionReservations).Length == PluginConfig.MaxPlayers, $"{"PositionReservations"} was {((Il2CppArrayBase<List<PositionReservation>>)(object)__instance.BotAIData.PositionReservations).Length} when the manual patch should have set it to {PluginConfig.MaxPlayers}.");
			L.Assert(((Il2CppArrayBase<List<ObjectReservation>>)(object)__instance.BotAIData.ObjectReservations).Length == PluginConfig.MaxPlayers, $"{"ObjectReservations"} was {((Il2CppArrayBase<List<ObjectReservation>>)(object)__instance.BotAIData.ObjectReservations).Length} when the manual patch should have set it to {PluginConfig.MaxPlayers}.");
			for (int i = 4; i < PluginConfig.MaxPlayers; i++)
			{
				((Il2CppArrayBase<List<PositionReservation>>)(object)__instance.BotAIData.PositionReservations)[i] = new List<PositionReservation>((int)PluginConfig.MaxPlayers);
				((Il2CppArrayBase<List<ObjectReservation>>)(object)__instance.BotAIData.ObjectReservations)[i] = new List<ObjectReservation>((int)PluginConfig.MaxPlayers);
			}
		}

		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(PlayerManager __instance)
		{
			L.Assert((Object)(object)__instance != (Object)null, "__instance was null");
			FixAvailableSpawnpoints(__instance);
			FixPlayerColors(__instance);
		}

		private static Color GenerateSeededRandomColor(float saturation = 0.8f, float value = 0.8f)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return Color.HSVToRGB(_random.NextSingle(), saturation, value);
		}

		private static void FixPlayerColors(PlayerManager __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[4]
			{
				ColorExt.Hex("FFA500"),
				Color.yellow,
				Color.magenta,
				Color.white
			};
			Il2CppStructArray<Color> playerColors = __instance.m_playerColors;
			__instance.m_playerColors = new Il2CppStructArray<Color>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < PluginConfig.MaxPlayers; i++)
			{
				Color val = ((i < 4) ? ((Il2CppArrayBase<Color>)(object)playerColors)[i] : ((i >= 8) ? GenerateSeededRandomColor() : array[i % 4]));
				Color val2 = val;
				((Il2CppArrayBase<Color>)(object)__instance.m_playerColors)[i] = val2;
			}
		}

		private static void FixAvailableSpawnpoints(PlayerManager playerManager)
		{
			int length = Enum.GetValues(typeof(PlayerspawnpointType)).Length;
			if (length != 5)
			{
				L.Warning($"{"PlayerspawnpointType"} contained {length} types, but {5} were expected. This may or may not work as expected!");
			}
			for (int i = 0; i < length; i++)
			{
				((Il2CppArrayBase<Il2CppReferenceArray<PlayerSpawnpoint>>)(object)playerManager.m_availableSpawnpoints)[i] = new Il2CppReferenceArray<PlayerSpawnpoint>((long)PluginConfig.MaxPlayers);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerVoiceManager))]
	public static class PlayerVoiceManagerPatch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(PlayerVoiceManager __instance)
		{
			if (((Il2CppArrayBase<PlayerVoice>)(object)__instance.m_playerVoices).Length < PluginConfig.MaxPlayers)
			{
				__instance.m_playerVoices = new Il2CppReferenceArray<PlayerVoice>((long)PluginConfig.MaxPlayers);
			}
		}
	}
	[HarmonyPatch(typeof(PUI_Compass))]
	public static class PUI_CompassPatch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(PUI_Compass __instance)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			__instance.m_playerPingMarkers = new Il2CppReferenceArray<NavMarker>((long)PluginConfig.MaxPlayers);
			__instance.m_playerNameMarkers = new Il2CppReferenceArray<NavMarker>((long)PluginConfig.MaxPlayers);
			__instance.m_playerMarkersWorldPos = new Il2CppStructArray<Vector3>((long)PluginConfig.MaxPlayers);
			__instance.m_playerPingMarkersActive = new Il2CppStructArray<bool>((long)PluginConfig.MaxPlayers);
			__instance.m_playerNameMarkersVisible = new Il2CppStructArray<bool>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < PluginConfig.MaxPlayers; i++)
			{
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerPingMarkers)[i] = __instance.SpawnCompassObj(__instance.m_playerMarkerPrefab, 0f, 0f, false).GetComponent<NavMarker>();
				((Component)((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerPingMarkers)[i]).transform.localEulerAngles = new Vector3(0f, 0f, 180f);
				((Component)((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerPingMarkers)[i]).transform.localScale = new Vector3(__instance.m_navMarkerScale, __instance.m_navMarkerScale, __instance.m_navMarkerScale);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerPingMarkers)[i].SetVisible(false);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerPingMarkers)[i].SetPinEnabled(true);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i] = __instance.SpawnCompassObj(__instance.m_playerMarkerPrefab, 0f, 0f, false).GetComponent<NavMarker>();
				((Component)((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i]).transform.localScale = new Vector3(__instance.m_navMarkerScale, __instance.m_navMarkerScale, __instance.m_navMarkerScale);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i].SetStyle((eNavMarkerStyle)12);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i].SetState((NavMarkerState)1);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i].SetVisible(false);
				((Il2CppArrayBase<NavMarker>)(object)__instance.m_playerNameMarkers)[i].SetPinEnabled(false);
				((Il2CppArrayBase<bool>)(object)__instance.m_playerPingMarkersActive)[i] = false;
			}
		}
	}
	[HarmonyPatch(typeof(SNet_Core))]
	public static class SNet_CorePatch
	{
		[HarmonyPatch("GetBotNickname")]
		[HarmonyPostfix]
		public static void GetBotNickname__Postfix(ref string __result, int characterIndex)
		{
			if (characterIndex > 3)
			{
				__result = PluginConfig.GetExtraSlotNickname(characterIndex);
			}
		}
	}
	[HarmonyPatch(typeof(SNet_LobbyManager))]
	public class SNet_LobbyManagerPatch
	{
		[HarmonyPatch("CreateLobby")]
		[HarmonyPrefix]
		public static bool CreateLobby__Prefix(SNet_LobbySettings settings, bool leaveSessionHub)
		{
			if (settings.m_playerLimit < PluginConfig.MaxPlayers)
			{
				settings.m_playerLimit = PluginConfig.MaxPlayers;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SNet_PlayerSlotManager))]
	public static class SNet_PlayerSlotManagerPatch
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		public static void Setup__Postfix(SNet_PlayerSlotManager __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			__instance.PlayerSlots = new Il2CppReferenceArray<SNet_Slot>((long)PluginConfig.MaxPlayers);
			__instance.CharacterSlots = new Il2CppReferenceArray<SNet_Slot>((long)PluginConfig.MaxPlayers);
			__instance.m_playerSlotPermissions = new Il2CppStructArray<SlotPermission>((long)PluginConfig.MaxPlayers);
			for (int i = 0; i < PluginConfig.MaxPlayers; i++)
			{
				((Il2CppArrayBase<SNet_Slot>)(object)__instance.PlayerSlots)[i] = new SNet_Slot(i);
				((Il2CppArrayBase<SNet_Slot>)(object)__instance.CharacterSlots)[i] = new SNet_Slot(i);
				__instance.InternalSetSlotPermission(i, (SlotPermission)0, true);
				if (i > 3)
				{
					((Il2CppArrayBase<SlotPermission>)(object)__instance.m_playerSlotPermissions)[i] = PluginConfig.GetExtraSlotPermission(i);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SNet_SessionHub))]
	public static class SNet_SessionHubPatch
	{
		[HarmonyPatch("TryAddBotToSession")]
		[HarmonyPostfix]
		public static void TryAddBotToSession__Postfix(SNet_SessionHub __instance, ref bool __result, SNet_Player bot)
		{
			if (!__result && bot.IsBot && SNet.IsMaster && __instance.PlayersInSession.Count <= PluginConfig.MaxPlayers - 1 && !__instance.PlayersInSession.Contains(bot))
			{
				__instance.AddPlayerToSession(bot, true);
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(SteamMatchmaking))]
	public static class SteamMatchmakingPatch
	{
		[HarmonyPatch("CreateLobby")]
		[HarmonyPrefix]
		public static bool CreateLobby__Prefix(ELobbyType eLobbyType, ref int cMaxMembers)
		{
			if (cMaxMembers < PluginConfig.MaxPlayers)
			{
				cMaxMembers = PluginConfig.MaxPlayers;
			}
			return true;
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object? value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object? value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object? value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object? value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object? value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object? value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object? value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object? value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object? value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object? value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}