Decompiled source of UnlimitedMages v2.0.0

plugins/UnlimitedMages.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Dissonance;
using Dissonance.Integrations.FishNet;
using Dissonance.Networking;
using FishNet.Managing;
using FishNet.Transporting;
using FishySteamworks;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnlimitedMages.API;
using UnlimitedMages.Components;
using UnlimitedMages.System.Attributes;
using UnlimitedMages.System.Components;
using UnlimitedMages.System.Events;
using UnlimitedMages.System.Events.Types;
using UnlimitedMages.UI;
using UnlimitedMages.UI.Popup;
using UnlimitedMages.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UnlimitedMages")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ba11c4bb89ceb18d2c0c0221715e5ac8a2ec20cd")]
[assembly: AssemblyProduct("UnlimitedMages")]
[assembly: AssemblyTitle("UnlimitedMages")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UnlimitedMages
{
	[BepInPlugin("com.bisocm.unlimited_mages", "Unlimited Mages", "2.0.0")]
	[GameVersionCompatibility(new string[] { "0.7.4", "0.7.6" })]
	public class UnlimitedMagesPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource? Log;

		public static string modsync = "all";

		public const string ModVersion = "2.0.0";

		public const string ModName = "Unlimited Mages";

		public const string ModGuid = "com.bisocm.unlimited_mages";

		private void Awake()
		{
			Log = Logger.CreateLogSource("UnlimitedMages");
			EventBus.Subscribe<BootstrapReadyEvent>(OnBootstrapReady);
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Log.LogInfo((object)"Unlimited Mages Mod has been loaded and patched successfully!");
		}

		private void OnDestroy()
		{
			EventBus.Unsubscribe<BootstrapReadyEvent>(OnBootstrapReady);
		}

		private void OnBootstrapReady(BootstrapReadyEvent evt)
		{
			ManualLogSource? log = Log;
			if (log != null)
			{
				log.LogInfo((object)"BootstrapReady event received. Initializing mod systems...");
			}
			ComponentActivator.Inject(Log);
		}
	}
}
namespace UnlimitedMages.Utilities
{
	internal static class GameConstants
	{
		internal static class Game
		{
			internal const int OriginalTeamSize = 4;

			internal const int NumTeams = 2;

			internal const int MaxTeamSize = 128;

			internal const int MinimumTeamSize = 2;
		}

		internal static class BootstrapManager
		{
			internal const string OnGetLobbyListMethod = "OnGetLobbyList";

			internal const string OnLobbyEnteredMethod = "OnLobbyEntered";

			internal const string ChangeSceneAfterCleanupMethod = "ChangeSceneAfterCleanup";

			internal const string OnGetLobbyData = "OnGetLobbyData";

			internal const string HasLeaveGameFinishedField = "hasLeaveGameFinished";

			internal const string OnLobbyCreatedMethod = "OnLobbyCreated";

			internal static string GetModdedVersionString()
			{
				return Application.version + "-UM";
			}
		}

		internal static class MainMenuManager
		{
			internal const string StartMethod = "Start";

			internal const string SyncHatsMethod = "SyncHats";

			internal const string ClampStringMethod = "ClampString";

			internal const string RemoveHatMethod = "RemoveHat";

			internal const string BodiesField = "bodies";

			internal const string PlayerNamesField = "playerNames";

			internal const string PlayerLevelAndRanksField = "playerLevelandRanks";

			internal const int PlayerNameClampLength = 10;
		}

		internal static class MainMenuManagerNetworked
		{
			internal const string StartMethod = "Start";

			internal const string ResetLocalTeamMethod = "ResetLocalTeam";

			internal const string Team1PlayersField = "team1players";

			internal const string Team2PlayersField = "team2players";
		}

		internal static class PlayerRespawnManager
		{
			internal const string OnStartClientMethod = "OnStartClient";

			internal const string FadeInVignetteMethod = "FadeInVignette";

			internal const string EndGameMethod = "EndGame";

			internal const string ServerPAsoundMethod = "ServerPAsound";

			internal const string PlayAnnouncerSoundMethod = "PlayAnnouncerSound";

			internal const string ScoreboardField = "scoreb";

			internal const string PositionsField = "positions";

			internal const string WarlocksSetField = "warlocksset";

			internal const string DeadPlayersField = "DeadPlayers";

			internal const float DeathMessageFirstY = 449f;

			internal const float DeathMessageLastY = 31.2f;
		}

		internal static class Networking
		{
			internal const float DissonanceSearchInterval = 1f;

			internal const string CommandPrefix = "[UNLIMITED_MAGES]";

			internal const char CommandDelimiter = ':';
		}
	}
}
namespace UnlimitedMages.UI
{
	internal class SliderInteractionHelper : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler
	{
		public bool IsBeingDragged { get; private set; }

		public void OnPointerDown(PointerEventData eventData)
		{
			IsBeingDragged = true;
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			IsBeingDragged = false;
		}
	}
	internal sealed class UnlimitedMagesSlider : MonoBehaviour, IModComponent
	{
		private const string TargetPanelName = "CreateLobbyMenu";

		private bool _isReady;

		private SliderInteractionHelper? _sliderHelper;

		private TextMeshProUGUI? _sliderLabel;

		private Slider? _teamSizeSlider;

		public static int SelectedTeamSize { get; private set; } = 2;


		private void Update()
		{
			if (_isReady && !((Object)(object)_teamSizeSlider != (Object)null))
			{
				GameObject val = GameObject.Find("CreateLobbyMenu");
				if ((Object)(object)val != (Object)null && val.activeInHierarchy)
				{
					AddSliderToPanel(val.transform);
				}
			}
		}

		private void OnDestroy()
		{
			EventBus.Unsubscribe<ConfigReadyEvent>(OnConfigReady_UpdateSlider);
		}

		public void Initialize(ManualLogSource log)
		{
			_isReady = true;
			EventBus.Subscribe<ConfigReadyEvent>(OnConfigReady_UpdateSlider);
		}

		private void AddSliderToPanel(Transform panelTransform)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Expected O, but got Unknown
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Expected O, but got Unknown
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)panelTransform.Find("LobbySizeSlider") != (Object)null)
			{
				return;
			}
			ManualLogSource? log = UnlimitedMagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Injecting team size slider into '" + ((Object)panelTransform).name + "'."));
			}
			Color color = default(Color);
			((Color)(ref color))..ctor(0.1f, 0.1f, 0.15f, 0.8f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.3f, 0.65f, 1f, 0.9f);
			Color color3 = default(Color);
			((Color)(ref color3))..ctor(0.9f, 0.9f, 0.9f, 1f);
			GameObject val = new GameObject("LobbySizeSlider");
			val.transform.SetParent(panelTransform, false);
			_teamSizeSlider = val.AddComponent<Slider>();
			_sliderHelper = val.AddComponent<SliderInteractionHelper>();
			((Graphic)val.AddComponent<Image>()).color = color;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(300f, 25f);
			Transform val2 = panelTransform.Find("CreateLobby");
			Transform val3 = panelTransform.Find("back (1)");
			if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
			{
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				RectTransform component3 = ((Component)val3).GetComponent<RectTransform>();
				Vector2 anchoredPosition = component2.anchoredPosition;
				float num = -80f;
				component2.anchoredPosition += new Vector2(0f, num);
				component3.anchoredPosition += new Vector2(0f, num);
				component.anchoredPosition = anchoredPosition;
			}
			else
			{
				ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"Could not find 'CreateLobby' or 'back (1)' buttons. Slider will be placed at a default position.");
				}
				component.anchoredPosition = new Vector2(0f, -100f);
			}
			GameObject val4 = new GameObject("Fill");
			val4.transform.SetParent((Transform)(object)component, false);
			((Graphic)val4.AddComponent<Image>()).color = color2;
			_teamSizeSlider.fillRect = val4.GetComponent<RectTransform>();
			_teamSizeSlider.fillRect.anchorMin = new Vector2(0f, 0f);
			_teamSizeSlider.fillRect.anchorMax = new Vector2(0f, 1f);
			_teamSizeSlider.fillRect.pivot = new Vector2(0f, 0.5f);
			_teamSizeSlider.fillRect.sizeDelta = Vector2.zero;
			GameObject val5 = new GameObject("Handle");
			val5.transform.SetParent((Transform)(object)component, false);
			Image val6 = val5.AddComponent<Image>();
			((Graphic)val6).color = color3;
			_teamSizeSlider.handleRect = val5.GetComponent<RectTransform>();
			((Selectable)_teamSizeSlider).targetGraphic = (Graphic)(object)val6;
			_teamSizeSlider.handleRect.sizeDelta = new Vector2(15f, 25f);
			GameObject val7 = new GameObject("LobbySizeLabel");
			val7.transform.SetParent(val.transform, false);
			_sliderLabel = val7.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_sliderLabel).fontSize = 20f;
			((Graphic)_sliderLabel).color = Color.white;
			((TMP_Text)_sliderLabel).alignment = (TextAlignmentOptions)514;
			RectTransform component4 = val7.GetComponent<RectTransform>();
			component4.anchoredPosition = new Vector2(0f, 30f);
			component4.sizeDelta = new Vector2(300f, 30f);
			_teamSizeSlider.direction = (Direction)0;
			_teamSizeSlider.minValue = 2f;
			_teamSizeSlider.maxValue = 128f;
			_teamSizeSlider.wholeNumbers = true;
			_teamSizeSlider.value = SelectedTeamSize;
			UpdateSliderDisplay((int)_teamSizeSlider.value);
			((UnityEvent<float>)(object)_teamSizeSlider.onValueChanged).AddListener((UnityAction<float>)OnSliderValueChanged);
		}

		private void OnSliderValueChanged(float value)
		{
			int num = (int)value;
			UpdateSliderDisplay(num);
			SelectedTeamSize = num;
			ConfigManager instance = ConfigManager.Instance;
			if (instance != null && instance.IsConfigReady)
			{
				EventBus.Publish(new HostTeamSizeChangedEvent(num));
			}
		}

		private void UpdateSliderDisplay(int value)
		{
			if ((Object)(object)_sliderLabel != (Object)null)
			{
				((TMP_Text)_sliderLabel).text = $"Team Size: {value} vs {value}";
			}
		}

		private void OnConfigReady_UpdateSlider(ConfigReadyEvent evt)
		{
			if (!((Object)(object)_sliderLabel == (Object)null) && !((Object)(object)_teamSizeSlider == (Object)null) && (!((Object)(object)_sliderHelper != (Object)null) || !_sliderHelper.IsBeingDragged))
			{
				UpdateSliderDisplay(evt.TeamSize);
				_teamSizeSlider.SetValueWithoutNotify((float)evt.TeamSize);
			}
		}
	}
}
namespace UnlimitedMages.UI.Popup
{
	internal enum PopupButton
	{
		Ok,
		Warning,
		Error
	}
	internal readonly struct PopupButtonData
	{
		public PopupButton Type { get; }

		public string Text { get; }

		public PopupButtonData(PopupButton type, string text)
		{
			Type = type;
			Text = text;
		}
	}
	internal sealed class UnlimitedMagesPopup : MonoBehaviour
	{
		private List<PopupButtonData> _buttons = new List<PopupButtonData>();

		private Dictionary<PopupButton, GUIStyle> _buttonStyles = new Dictionary<PopupButton, GUIStyle>();

		private GameObject? _inputBlocker;

		private bool _isVisible;

		private GUIStyle _labelStyle = new GUIStyle();

		private string _message = "";

		private Action<PopupButton> _onButtonClicked = delegate
		{
		};

		private bool _stylesInitialized;

		private string _title = "";

		private Rect _windowRect;

		private GUIStyle _windowStyle = new GUIStyle();

		private void Update()
		{
			if (_isVisible)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_inputBlocker != (Object)null)
			{
				Object.Destroy((Object)(object)_inputBlocker);
			}
		}

		private void OnGUI()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (_isVisible)
			{
				InitializeStyles();
				((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
				((Rect)(ref _windowRect)).y = ((float)Screen.height - ((Rect)(ref _windowRect)).height) / 2f;
				GUI.ModalWindow(0, _windowRect, new WindowFunction(DrawWindow), _title, _windowStyle);
			}
		}

		public static void Show(string title, string message, Action<PopupButton> onButtonClicked, params PopupButtonData[] buttons)
		{
			//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_001e: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Object.FindFirstObjectByType<UnlimitedMagesPopup>() != (Object)null))
			{
				GameObject val = new GameObject("UnlimitedMages_Popup");
				Object.DontDestroyOnLoad((Object)val);
				UnlimitedMagesPopup unlimitedMagesPopup = val.AddComponent<UnlimitedMagesPopup>();
				unlimitedMagesPopup._title = title;
				unlimitedMagesPopup._message = message;
				unlimitedMagesPopup._onButtonClicked = onButtonClicked;
				unlimitedMagesPopup._buttons = ((buttons.Length != 0) ? buttons.ToList() : new List<PopupButtonData>
				{
					new PopupButtonData(PopupButton.Ok, "OK")
				});
				unlimitedMagesPopup.CreateInputBlocker();
				unlimitedMagesPopup._isVisible = true;
				unlimitedMagesPopup._windowRect = new Rect((float)((Screen.width - 600) / 2), (float)((Screen.height - 320) / 2), 600f, 320f);
			}
		}

		private void CreateInputBlocker()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			_inputBlocker = new GameObject("UIPopupBlocker");
			Object.DontDestroyOnLoad((Object)(object)_inputBlocker);
			Canvas obj = _inputBlocker.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 32767;
			_inputBlocker.AddComponent<GraphicRaycaster>();
			GameObject val = new GameObject("BlockerPanel");
			val.transform.SetParent(_inputBlocker.transform, false);
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = Color.clear;
			((Graphic)obj2).raycastTarget = true;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.sizeDelta = Vector2.zero;
		}

		private static Texture2D CreateSolidColorTexture(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private GUIStyle CreateButtonStyle(Color hoverColor)
		{
			//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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00c5: Expected O, but got Unknown
			Color color = default(Color);
			((Color)(ref color))..ctor(0.2f, 0.22f, 0.25f, 1f);
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = 16,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			val.normal.background = CreateSolidColorTexture(color);
			val.normal.textColor = Color.white;
			val.hover.background = CreateSolidColorTexture(hoverColor);
			val.hover.textColor = Color.white;
			val.active.background = CreateSolidColorTexture(hoverColor);
			val.border = new RectOffset(0, 0, 0, 0);
			val.padding = new RectOffset(10, 10, 12, 12);
			val.margin = new RectOffset(5, 5, 0, 0);
			return val;
		}

		private void InitializeStyles()
		{
			//IL_001d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01b0: Expected O, but got Unknown
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			if (!_stylesInitialized)
			{
				Color color = new Color(0.12f, 0.13f, 0.16f, 1f);
				Color textColor = default(Color);
				((Color)(ref textColor))..ctor(0.9f, 0.9f, 0.9f, 1f);
				Texture2D background = CreateSolidColorTexture(color);
				GUIStyle val = new GUIStyle();
				val.normal.background = background;
				val.normal.textColor = Color.white;
				val.active.background = background;
				val.active.textColor = Color.white;
				val.hover.background = background;
				val.hover.textColor = Color.white;
				val.focused.background = background;
				val.focused.textColor = Color.white;
				val.onNormal.background = background;
				val.onNormal.textColor = Color.white;
				val.onActive.background = background;
				val.onActive.textColor = Color.white;
				val.onHover.background = background;
				val.onHover.textColor = Color.white;
				val.onFocused.background = background;
				val.onFocused.textColor = Color.white;
				val.padding = new RectOffset(10, 10, 10, 10);
				val.border = new RectOffset(2, 2, 2, 2);
				val.fontSize = 20;
				val.fontStyle = (FontStyle)1;
				val.alignment = (TextAnchor)1;
				_windowStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					wordWrap = true,
					alignment = (TextAnchor)0
				};
				val2.normal.textColor = textColor;
				val2.padding = new RectOffset(15, 15, 15, 15);
				_labelStyle = val2;
				_buttonStyles = new Dictionary<PopupButton, GUIStyle>
				{
					[PopupButton.Ok] = CreateButtonStyle(new Color(0.3f, 0.65f, 1f, 1f)),
					[PopupButton.Warning] = CreateButtonStyle(new Color(1f, 0.75f, 0f, 1f)),
					[PopupButton.Error] = CreateButtonStyle(new Color(0.9f, 0.2f, 0.2f, 1f))
				};
				_stylesInitialized = true;
			}
		}

		private void DrawWindow(int windowID)
		{
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Space(22f);
			GUILayout.Label(_message, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			using (IEnumerator<PopupButtonData> enumerator = _buttons.Where((PopupButtonData button) => GUILayout.Button(button.Text.ToUpper(), _buttonStyles[button.Type], (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(120f)
			})).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					PopupButtonData current = enumerator.Current;
					_isVisible = false;
					_onButtonClicked(current.Type);
					Object.Destroy((Object)(object)((Component)this).gameObject);
					return;
				}
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			GUILayout.EndVertical();
			GUI.DragWindow();
		}
	}
}
namespace UnlimitedMages.System.Events
{
	internal static class EventBus
	{
		private static readonly Dictionary<Type, Delegate> SEvents = new Dictionary<Type, Delegate>();

		public static void Subscribe<T>(Action<T> listener)
		{
			Type typeFromHandle = typeof(T);
			if (SEvents.TryGetValue(typeFromHandle, out Delegate value))
			{
				SEvents[typeFromHandle] = Delegate.Combine(value, listener);
			}
			else
			{
				SEvents[typeFromHandle] = listener;
			}
		}

		public static void Unsubscribe<T>(Action<T> listener)
		{
			Type typeFromHandle = typeof(T);
			if (SEvents.TryGetValue(typeFromHandle, out Delegate value))
			{
				Delegate @delegate = Delegate.Remove(value, listener);
				if ((object)@delegate == null)
				{
					SEvents.Remove(typeFromHandle);
				}
				else
				{
					SEvents[typeFromHandle] = @delegate;
				}
			}
		}

		public static void Publish<T>(T message)
		{
			if (SEvents.TryGetValue(typeof(T), out Delegate value))
			{
				value.DynamicInvoke(message);
			}
		}
	}
}
namespace UnlimitedMages.System.Events.Types
{
	internal class BootstrapReadyEvent
	{
	}
	internal class ConfigReadyEvent
	{
		public readonly int TeamSize;

		public ConfigReadyEvent(int teamSize)
		{
			TeamSize = teamSize;
			base..ctor();
		}
	}
	internal class HostTeamSizeChangedEvent
	{
		public readonly int NewTeamSize;

		public HostTeamSizeChangedEvent(int newTeamSize)
		{
			NewTeamSize = newTeamSize;
			base..ctor();
		}
	}
}
namespace UnlimitedMages.System.Components
{
	internal sealed class CompatibilityChecker : MonoBehaviour, IModComponent
	{
		private static bool IsVerified { get; set; }

		public void Initialize(ManualLogSource log)
		{
			if (IsVerified)
			{
				return;
			}
			log.LogInfo((object)"[CompatibilityChecker] Checking game version compatibility...");
			Type type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault((Type t) => typeof(UnlimitedMagesPlugin) == t);
			if (type == null)
			{
				log.LogWarning((object)"[CompatibilityChecker] Could not find the BaseUnityPlugin class. Skipping check.");
				IsVerified = true;
				return;
			}
			GameVersionCompatibilityAttribute customAttribute = type.GetCustomAttribute<GameVersionCompatibilityAttribute>();
			BepInPlugin customAttribute2 = ((MemberInfo)type).GetCustomAttribute<BepInPlugin>();
			if (customAttribute == null)
			{
				log.LogInfo((object)"[CompatibilityChecker] No GameVersionCompatibilityAttribute found. Assuming compatibility.");
				IsVerified = true;
			}
			else
			{
				PerformCheck(log, customAttribute, customAttribute2.Name);
			}
		}

		private void PerformCheck(ManualLogSource log, GameVersionCompatibilityAttribute attribute, string modName)
		{
			string version = Application.version;
			if (!attribute.CompatibleVersions.Contains(version))
			{
				log.LogWarning((object)"--- GAME VERSION INCOMPATIBILITY DETECTED ---");
				log.LogWarning((object)("Mod: " + modName));
				log.LogWarning((object)("Current Game Version: " + version));
				log.LogWarning((object)("Compatible Versions: " + string.Join(", ", attribute.CompatibleVersions)));
				log.LogWarning((object)"This mod may cause crashes or unexpected behavior. Proceed with caution.");
				log.LogWarning((object)"---------------------------------------------");
				ShowIncompatibilityAlert(modName, version, attribute.CompatibleVersions);
			}
			else
			{
				log.LogInfo((object)("[CompatibilityChecker] Game version check passed. Current: " + version));
			}
			IsVerified = true;
		}

		private void ShowIncompatibilityAlert(string modName, string currentVersion, string[] compatibleVersions)
		{
			string title = "Mod Compatibility Warning";
			string message = "The mod <b>" + modName + "</b> has not been marked as compatible with your current game version.\n\n<b>Your Version:</b>\n<size=18>" + currentVersion + "</size>\n\n<b>Compatible Versions:</b>\n<size=18>" + string.Join(", ", compatibleVersions) + "</size>\n\n<color=yellow>Using an incompatible version may cause issues. Proceed with caution.</color>\n<size=12><color=grey>If you observe any bugs - please report them in the Modding Discord or using the GitHub Issues!</color></size>";
			UnlimitedMagesPopup.Show(title, message, delegate
			{
			}, new PopupButtonData(PopupButton.Warning, "OK"));
		}
	}
	internal sealed class ConfigManager : MonoBehaviour, IModComponent
	{
		public static ConfigManager? Instance { get; private set; }

		public int TeamSize { get; private set; } = 2;


		public bool IsConfigReady { get; private set; }

		public void Reset()
		{
			ManualLogSource? log = UnlimitedMagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Resetting session configuration.");
			}
			IsConfigReady = false;
			TeamSize = 2;
		}

		public void Initialize(ManualLogSource log)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				Instance = this;
			}
		}

		public void FinalizeConfig(int teamSize)
		{
			if (!IsConfigReady || teamSize != TeamSize)
			{
				TeamSize = teamSize;
				IsConfigReady = true;
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Config finalized. Team Size: {TeamSize}");
				}
				EventBus.Publish(new ConfigReadyEvent(TeamSize));
				UnlimitedMagesAPI.RaiseConfigReady(teamSize);
			}
		}
	}
}
namespace UnlimitedMages.System.Attributes
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	internal class GameVersionCompatibilityAttribute : Attribute
	{
		public string[] CompatibleVersions { get; }

		public GameVersionCompatibilityAttribute(params string[] compatibleVersions)
		{
			CompatibleVersions = compatibleVersions;
			base..ctor();
		}
	}
}
namespace UnlimitedMages.Patches
{
	[HarmonyPatch(typeof(BootstrapManager))]
	internal static class BootstrapManagerPatches
	{
		private static bool _eventFired;

		[HarmonyPatch(typeof(BootstrapManager), "OnLobbyCreated")]
		[HarmonyPostfix]
		public static void OnLobbyCreated_Postfix(LobbyCreated_t callback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((int)callback.m_eResult == 1)
			{
				CSteamID val = new CSteamID(callback.m_ulSteamIDLobby);
				SteamMatchmaking.SetLobbyData(val, "Version", GameConstants.BootstrapManager.GetModdedVersionString());
				SteamMatchmaking.SetLobbyData(val, "com.bisocm.unlimited_mages", "2.0.0");
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)string.Format("Tagged lobby {0} as modded with version {1}.", callback.m_ulSteamIDLobby, "2.0.0"));
				}
			}
		}

		[HarmonyPatch(typeof(BootstrapManager), "GetLobbiesList")]
		[HarmonyPrefix]
		public static void GetLobbiesList_Prefix()
		{
			SteamMatchmaking.AddRequestLobbyListStringFilter("com.bisocm.unlimited_mages", "2.0.0", (ELobbyComparison)0);
		}

		[HarmonyPatch(typeof(BootstrapManager), "GetLobbiesList")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> GetLobbiesList_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Application), "version");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(GameConstants.BootstrapManager), "GetModdedVersionString", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Patching GetLobbiesList to search for modded version string...");
					}
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
					ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"Successfully patched GetLobbiesList.");
					}
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake_Postfix()
		{
			if (!_eventFired)
			{
				EventBus.Publish(new BootstrapReadyEvent());
				_eventFired = true;
			}
		}

		[HarmonyPatch("CreateLobby", new Type[] { typeof(bool) })]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CreateLobby_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return TranspileGetTeamSize(instructions, multiplyByTeams: true);
		}

		[HarmonyPatch("OnGetLobbyList")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> OnGetLobbyList_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return TranspileAllowAnyTeamSize(instructions);
		}

		[HarmonyPatch("OnLobbyEntered")]
		[HarmonyPostfix]
		public static void OnLobbyEntered_Postfix(LobbyEnter_t callback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (SteamMatchmaking.GetLobbyOwner(new CSteamID(callback.m_ulSteamIDLobby)) == SteamUser.GetSteamID())
			{
				return;
			}
			int lobbyMemberLimit = SteamMatchmaking.GetLobbyMemberLimit(new CSteamID(callback.m_ulSteamIDLobby));
			if (lobbyMemberLimit > 8)
			{
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Client entered lobby. Correcting max players to Steam value: {lobbyMemberLimit}");
				}
			}
		}

		[HarmonyPatch("ChangeSceneAfterCleanup", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		public static bool ChangeSceneAfterCleanup_Prefix(string sceneName, ref IEnumerator __result)
		{
			__result = CustomChangeSceneAfterCleanup(sceneName);
			return false;
		}

		[HarmonyPatch(typeof(BootstrapManager), "OnGetLobbyData")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> OnGetLobbyData_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Application), "version");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(GameConstants.BootstrapManager), "GetModdedVersionString", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Patching OnGetLobbyData to use modded version string...");
					}
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
					ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"Successfully patched OnGetLobbyData version check.");
					}
					break;
				}
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(SteamMatchmaking), "GetNumLobbyMembers", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(SteamMatchmaking), "GetLobbyMemberLimit", (Type[])null, (Type[])null);
			for (int j = 0; j < list.Count; j++)
			{
				if (CodeInstructionExtensions.Calls(list[j], methodInfo3) && j + 1 < list.Count && !(list[j + 1].opcode != OpCodes.Ldc_I4_8))
				{
					ManualLogSource? log3 = UnlimitedMagesPlugin.Log;
					if (log3 != null)
					{
						log3.LogInfo((object)"Patching OnGetLobbyData to use dynamic lobby limit...");
					}
					CodeInstruction val = list[j - 2];
					CodeInstruction val2 = list[j - 1];
					list[j + 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo4);
					list.Insert(j + 1, val2.Clone());
					list.Insert(j + 1, val.Clone());
					ManualLogSource? log4 = UnlimitedMagesPlugin.Log;
					if (log4 != null)
					{
						log4.LogInfo((object)"Successfully patched OnGetLobbyData.");
					}
					break;
				}
			}
			return list;
		}

		private static IEnumerator CustomChangeSceneAfterCleanup(string sceneName)
		{
			DissonanceFishNetComms val = Object.FindFirstObjectByType<DissonanceFishNetComms>();
			if ((Object)(object)val != (Object)null)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(DissonanceFishNetComms), "stopit", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Calling stopit() on DissonanceFishNetComms.");
					}
					methodInfo.Invoke(val, null);
				}
				else
				{
					ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"Could not find 'stopit' method on DissonanceFishNetComms. VoIP cleanup might be incomplete.");
					}
				}
			}
			yield return null;
			DissonanceComms val2 = Object.FindFirstObjectByType<DissonanceComms>();
			if ((Object)(object)val2 != (Object)null)
			{
				ManualLogSource? log3 = UnlimitedMagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"Destroying DissonanceComms GameObject.");
				}
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			NetworkManager val3 = Object.FindFirstObjectByType<NetworkManager>();
			FishySteamworks val4 = Object.FindFirstObjectByType<FishySteamworks>();
			if (BootstrapManager.CurrentLobbyID != 0L)
			{
				SteamMatchmaking.LeaveLobby(new CSteamID(BootstrapManager.CurrentLobbyID));
				BootstrapManager.CurrentLobbyID = 0uL;
			}
			if ((Object)(object)val3 != (Object)null)
			{
				if (val3.ServerManager.Started)
				{
					val3.ServerManager.StopConnection(true);
				}
				if (val3.ClientManager.Started)
				{
					val3.ClientManager.StopConnection();
				}
			}
			if ((Object)(object)val4 != (Object)null)
			{
				((Transport)val4).StopConnection(false);
				((Transport)val4).StopConnection(true);
			}
			yield return (object)new WaitForSeconds(0.5f);
			GameObject[] array = GameObject.FindGameObjectsWithTag("playbackprefab");
			for (int i = 0; i < array.Length; i++)
			{
				Object.Destroy((Object)(object)array[i]);
			}
			yield return null;
			SceneManager.LoadScene(sceneName);
			if (!((Object)(object)BootstrapManager.instance == (Object)null))
			{
				BootstrapManager.instance.GoToMenu();
				AccessTools.Field(typeof(BootstrapManager), "hasLeaveGameFinished").SetValue(BootstrapManager.instance, true);
			}
		}

		private static IEnumerable<CodeInstruction> TranspileAllowAnyTeamSize(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(SteamMatchmaking), "GetLobbyMemberLimit", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo) && i + 1 < list.Count && !(list[i + 1].opcode != OpCodes.Ldc_I4_8))
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Patching OnGetLobbyList to allow visibility of all lobby sizes...");
					}
					list[i + 1] = new CodeInstruction(OpCodes.Dup, (object)null);
					ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"Successfully patched OnGetLobbyList.");
					}
					break;
				}
			}
			return list;
		}

		private static IEnumerable<CodeInstruction> TranspileGetTeamSize(IEnumerable<CodeInstruction> instructions, bool multiplyByTeams)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			OpCode opCode = (multiplyByTeams ? OpCodes.Ldc_I4_8 : OpCodes.Ldc_I4_4);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(UnlimitedMagesSlider), "SelectedTeamSize");
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != opCode))
				{
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
					if (multiplyByTeams)
					{
						list.Insert(i + 1, new CodeInstruction(OpCodes.Ldc_I4, (object)2));
						list.Insert(i + 2, new CodeInstruction(OpCodes.Mul, (object)null));
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(MainMenuManagerNetworked))]
	internal static class MainMenuManagerNetworkedPatches
	{
		static MainMenuManagerNetworkedPatches()
		{
			EventBus.Subscribe<ConfigReadyEvent>(OnConfigReady_ResizeTeamArrays);
		}

		[HarmonyPatch("ResetLocalTeam")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> ResetLocalTeam_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return TranspileResizeTeamArrays(TranspileResizeTeamArrays(instructions, "team1players"), "team2players");
		}

		[HarmonyPatch("Start")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Start_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return TranspileResizeTeamArrays(TranspileResizeTeamArrays(instructions, "team1players"), "team2players");
		}

		private static void OnConfigReady_ResizeTeamArrays(ConfigReadyEvent evt)
		{
			MainMenuManagerNetworked val = Object.FindFirstObjectByType<MainMenuManagerNetworked>();
			if (!((Object)(object)val == (Object)null))
			{
				int teamSize = evt.TeamSize;
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Session config ready. Resizing MainMenuManagerNetworked arrays to size {teamSize}.");
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(MainMenuManagerNetworked), "team1players");
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(MainMenuManagerNetworked), "team2players");
				fieldInfo.SetValue(val, new string[teamSize]);
				fieldInfo2.SetValue(val, new string[teamSize]);
			}
		}

		private static IEnumerable<CodeInstruction> TranspileResizeTeamArrays(IEnumerable<CodeInstruction> instructions, string targetFieldName)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo fieldInfo = AccessTools.Field(typeof(MainMenuManagerNetworked), targetFieldName);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(ConfigManager), "Instance");
			MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(ConfigManager), "TeamSize");
			for (int i = 0; i < list.Count; i++)
			{
				if (i + 2 < list.Count && !(list[i].opcode != OpCodes.Ldc_I4_4) && !(list[i + 1].opcode != OpCodes.Newarr) && !(list[i + 2].opcode != OpCodes.Stfld) && !(list[i + 2].operand as FieldInfo != fieldInfo))
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("Transpiling " + targetFieldName + " initialization..."));
					}
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
					list.Insert(i + 1, new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2));
					ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("Successfully patched " + targetFieldName + " size."));
					}
					break;
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(MainMenuManager))]
	internal static class MainMenuManagerPatches
	{
		private static bool _isLobbyUiReady;

		private static readonly List<(string name, string rank, string steamId)> PendingPlayers = new List<(string, string, string)>();

		private static Coroutine? _timeoutCoroutine;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix(MainMenuManager __instance)
		{
			_isLobbyUiReady = false;
			PendingPlayers.Clear();
			EventBus.Unsubscribe<ConfigReadyEvent>(OnConfigReady_ResizeLobbyUI);
			EventBus.Subscribe<ConfigReadyEvent>(OnConfigReady_ResizeLobbyUI);
			if (_timeoutCoroutine != null)
			{
				((MonoBehaviour)__instance).StopCoroutine(_timeoutCoroutine);
			}
			_timeoutCoroutine = ((MonoBehaviour)__instance).StartCoroutine(LobbyUiTimeoutCoroutine());
		}

		private static IEnumerator LobbyUiTimeoutCoroutine()
		{
			yield return (object)new WaitForSeconds(15f);
			if (!_isLobbyUiReady)
			{
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"Timed out waiting for host config. Building UI with default size to prevent deadlock.");
				}
				OnConfigReady_ResizeLobbyUI(new ConfigReadyEvent(4));
			}
		}

		private static void OnConfigReady_ResizeLobbyUI(ConfigReadyEvent evt)
		{
			MainMenuManager val = Object.FindFirstObjectByType<MainMenuManager>();
			if ((Object)(object)val == (Object)null || _isLobbyUiReady)
			{
				return;
			}
			int teamSize = evt.TeamSize;
			ManualLogSource? log = UnlimitedMagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Received team size {teamSize}. Resizing lobby UI elements...");
			}
			int num = teamSize * 2;
			AccessTools.Field(typeof(MainMenuManager), "bodies").SetValue(val, new GameObject[num]);
			AccessTools.Field(typeof(MainMenuManager), "playerNames").SetValue(val, new string[num]);
			AccessTools.Field(typeof(MainMenuManager), "playerLevelandRanks").SetValue(val, new string[num]);
			ResizeUiList(ref val.team1, teamSize);
			ResizeUiList(ref val.team2, teamSize);
			ResizeUiList(ref val.team1rankandleveltext, teamSize);
			ResizeUiList(ref val.team2rankandleveltext, teamSize);
			ResizeUiList(ref val.texts, num * 2);
			ResizeUiList(ref val.rankandleveltext, num);
			ResizeAndWrapHats(ref val.hats, num);
			_isLobbyUiReady = true;
			ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"Processing {PendingPlayers.Count} pending players...");
			}
			foreach (var pendingPlayer in PendingPlayers)
			{
				val.SyncHats(pendingPlayer.name, pendingPlayer.rank, pendingPlayer.steamId);
			}
			PendingPlayers.Clear();
		}

		private static void ResizeUiList(ref Text[] array, int newSize)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (array.Length >= newSize || array.Length < 1)
			{
				return;
			}
			int num = array.Length;
			Text[] array2 = (Text[])(object)new Text[newSize];
			Array.Copy(array, array2, num);
			Text val = array[0];
			Transform parent = ((Component)val).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			for (int i = num; i < newSize; i++)
			{
				Text val2 = Object.Instantiate<Text>(val, parent);
				((Object)val2).name = $"{((Object)val).name}_Clone_{i}";
				val2.text = "";
				array2[i] = val2;
			}
			array = array2;
			if (array.Length == 0)
			{
				return;
			}
			int num2 = 4;
			? val3 = ((array.Length > 1) ? (((Component)array[1]).transform.localPosition - ((Component)array[0]).transform.localPosition) : new Vector3(0f, -35f, 0f));
			float num3 = Mathf.Clamp((float)num2 / (float)newSize, 0.5f, 1f);
			Vector3 val4 = (Vector3)val3 * num3;
			Vector3 localPosition = ((Component)array[0]).transform.localPosition;
			for (int j = 0; j < array.Length; j++)
			{
				bool flag = j < newSize;
				((Component)array[j]).gameObject.SetActive(flag);
				if (flag)
				{
					((Component)array[j]).transform.localPosition = localPosition + val4 * (float)j;
					((Component)array[j]).transform.localScale = Vector3.one * num3;
				}
			}
		}

		private static void ResizeAndWrapHats(ref GameObject[] array, int newSize)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			if (array.Length >= newSize)
			{
				for (int i = 0; i < array.Length; i++)
				{
					array[i].SetActive(i < newSize);
				}
			}
			else
			{
				if (array.Length < 1)
				{
					return;
				}
				int num = array.Length;
				GameObject[] array2 = (GameObject[])(object)new GameObject[newSize];
				Array.Copy(array, array2, num);
				GameObject val = array[0];
				Transform parent = val.transform.parent;
				if ((Object)(object)parent == (Object)null)
				{
					return;
				}
				Vector3 val2 = ((array.Length > 1) ? (array[1].transform.position - array[0].transform.position) : Vector3.zero);
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(0f, ((Vector3)(ref val2)).magnitude * 2.5f, 0f);
				for (int j = num; j < newSize; j++)
				{
					int num2 = j % 4;
					int num3 = j / 4;
					Vector3 position = array[num2].transform.position;
					GameObject val4 = Object.Instantiate<GameObject>(val, parent);
					((Object)val4).name = $"{((Object)val).name}_Clone_{j}";
					Vector3 val5 = position + val3 * (float)num3;
					if (num3 % 2 != 0)
					{
						val5 += val2 * 0.5f;
					}
					val4.transform.position = val5;
					array2[j] = val4;
				}
				array = array2;
				for (int k = 0; k < array.Length; k++)
				{
					array[k].SetActive(k < newSize);
				}
			}
		}

		[HarmonyPatch("SmallMap")]
		[HarmonyPatch("LargeMap")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> MapSelect_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(ConfigManager), "Instance");
			MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(ConfigManager), "TeamSize");
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Ldc_I4_8))
				{
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
					list.Insert(i + 1, new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2));
					list.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_I4, (object)2));
					list.Insert(i + 3, new CodeInstruction(OpCodes.Mul, (object)null));
				}
			}
			return list;
		}

		[HarmonyPatch("SyncHats")]
		[HarmonyPrefix]
		public static bool SyncHats_Prefix(string PlayerName, string PlayerRank, string steamid)
		{
			if (_isLobbyUiReady)
			{
				return true;
			}
			PendingPlayers.Add((PlayerName, PlayerRank, steamid));
			return false;
		}

		[HarmonyPatch("SyncHats")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> SyncHats_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(KickPlayersHolder), "AddToDict", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MainMenuManager), "ClampString", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					List<CodeInstruction> collection = new List<CodeInstruction>
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldc_I4, (object)10),
						new CodeInstruction(OpCodes.Call, (object)methodInfo2)
					};
					list.RemoveAt(i - 2);
					list.InsertRange(i - 2, collection);
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("RemoveHat")]
		[HarmonyPostfix]
		public static void RemoveHat_Postfix(MainMenuManager __instance, string PlayerName)
		{
			string key = (string)AccessTools.Method(typeof(MainMenuManager), "ClampString", (Type[])null, (Type[])null).Invoke(__instance, new object[2] { PlayerName, 10 });
			Dictionary<string, string> dictionary = (Dictionary<string, string>)AccessTools.Field(typeof(KickPlayersHolder), "nametosteamid").GetValue(__instance.kickplayershold);
			if (dictionary != null && dictionary.ContainsKey(key))
			{
				dictionary.Remove(key);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerRespawnManager))]
	internal static class PlayerRespawnManagerPatches
	{
		[HarmonyPatch("OnStartClient")]
		[HarmonyPostfix]
		public static void OnStartClient_Postfix(PlayerRespawnManager __instance)
		{
			if ((Object)(object)ConfigManager.Instance == (Object)null || !ConfigManager.Instance.IsConfigReady)
			{
				return;
			}
			int teamSize = ConfigManager.Instance.TeamSize;
			int num = teamSize * 2;
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerRespawnManager), "positions");
			if (((float[])fieldInfo.GetValue(__instance)).Length != num)
			{
				float[] array = new float[num];
				float num2 = 449f;
				float num3 = 31.2f;
				float num4 = (num2 - num3) / (float)(num - 1);
				for (int i = 0; i < num; i++)
				{
					array[i] = num2 - (float)i * num4;
				}
				fieldInfo.SetValue(__instance, array);
				AccessTools.Field(typeof(PlayerRespawnManager), "warlocksset").SetValue(__instance, teamSize);
			}
		}

		[HarmonyPatch("FadeInVignette")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> FadeInVignette_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerRespawnManager), "warlocksset");
			for (int i = 0; i < list.Count; i++)
			{
				if (i + 1 < list.Count && !(list[i].opcode != OpCodes.Ldc_I4_4) && !(list[i + 1].opcode != OpCodes.Stfld) && !(list[i + 1].operand as FieldInfo != fieldInfo))
				{
					MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(ConfigManager), "Instance");
					list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
					MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(ConfigManager), "TeamSize");
					list.Insert(i + 1, new CodeInstruction(OpCodes.Callvirt, (object)methodInfo2));
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"Successfully transpiled FadeInVignette to use dynamic team size.");
					}
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("EndGame")]
		[HarmonyPostfix]
		public static void EndGame_Postfix(PlayerRespawnManager __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			GameObject val = (GameObject)AccessTools.Field(typeof(PlayerRespawnManager), "scoreb").GetValue(__instance);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ConfigManager? instance = ConfigManager.Instance;
			if (instance == null)
			{
				return;
			}
			_ = instance.TeamSize;
			if (false)
			{
				return;
			}
			int num = ConfigManager.Instance.TeamSize * 2;
			Transform transform = val.transform;
			int childCount = transform.childCount;
			if (childCount < num && childCount != 0)
			{
				GameObject gameObject = ((Component)transform.GetChild(0)).gameObject;
				for (int i = childCount; i < num; i++)
				{
					((Object)Object.Instantiate<GameObject>(gameObject, transform)).name = $"{((Object)gameObject).name}_Clone_{i}";
				}
			}
		}

		[HarmonyPatch("PlayAnnouncerSound")]
		[HarmonyPrefix]
		public static bool PlayAnnouncerSound_Prefix(PlayerRespawnManager __instance, int pteam)
		{
			List<GameObject> list = (List<GameObject>)AccessTools.Field(typeof(PlayerRespawnManager), "DeadPlayers").GetValue(__instance);
			int num = 0;
			int num2 = 0;
			PlayerMovement val = default(PlayerMovement);
			foreach (GameObject item in list)
			{
				if (!((Object)(object)item == (Object)null) && item.TryGetComponent<PlayerMovement>(ref val))
				{
					switch (val.playerTeam)
					{
					case 0:
						num++;
						break;
					case 2:
						num2++;
						break;
					}
				}
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerRespawnManager), "ServerPAsound", (Type[])null, (Type[])null);
			switch (pteam)
			{
			case 0:
				if (num > 0)
				{
					int num4 = Mathf.Clamp(num - 1, 0, 3);
					methodInfo.Invoke(__instance, new object[1] { num4 });
				}
				break;
			case 2:
				if (num2 > 0)
				{
					int num3 = Mathf.Clamp(num2 - 1, 0, 3);
					methodInfo.Invoke(__instance, new object[1] { num3 + 4 });
				}
				break;
			}
			if ((bool)AccessTools.Field(typeof(PlayerRespawnManager), "iscolosseum").GetValue(__instance))
			{
				list.Clear();
			}
			return false;
		}
	}
}
namespace UnlimitedMages.Networking
{
	internal sealed class SessionManager : MonoBehaviour, IModComponent
	{
		private DissonanceComms? _comms;

		private Coroutine? _findDissonanceCoroutine;

		private bool _networkStartedAndHandled;

		public static SessionManager? Instance { get; private set; }

		private void Update()
		{
			if (_networkStartedAndHandled || (Object)(object)_comms == (Object)null || !_comms.IsNetworkInitialized || (Object)(object)ConfigManager.Instance == (Object)null)
			{
				return;
			}
			_networkStartedAndHandled = true;
			if (IsHost())
			{
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[Host] Network initialized. Setting local config and preparing to broadcast.");
				}
				SetAndBroadcastTeamSize(UnlimitedMagesSlider.SelectedTeamSize);
			}
			else
			{
				ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"[Client] Network initialized. Requesting config from host.");
				}
				RequestConfigFromHost();
			}
		}

		private void OnDestroy()
		{
			if (_findDissonanceCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_findDissonanceCoroutine);
				_findDissonanceCoroutine = null;
			}
			if ((Object)(object)_comms != (Object)null)
			{
				_comms.Text.MessageReceived -= OnChatMessageReceived;
			}
			EventBus.Unsubscribe<HostTeamSizeChangedEvent>(OnHostTeamSizeChanged);
		}

		public void Initialize(ManualLogSource log)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			EventBus.Subscribe<HostTeamSizeChangedEvent>(OnHostTeamSizeChanged);
			_findDissonanceCoroutine = ((MonoBehaviour)this).StartCoroutine(FindDissonance());
		}

		private void OnHostTeamSizeChanged(HostTeamSizeChangedEvent evt)
		{
			SetAndBroadcastTeamSize(evt.NewTeamSize);
		}

		private IEnumerator FindDissonance()
		{
			ManualLogSource? log = UnlimitedMagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Searching for DissonanceComms...");
			}
			while ((Object)(object)_comms == (Object)null)
			{
				_comms = Object.FindFirstObjectByType<DissonanceComms>();
				if ((Object)(object)_comms == (Object)null)
				{
					yield return (object)new WaitForSeconds(1f);
				}
			}
			ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"DissonanceComms found! Subscribing to text messages.");
			}
			_comms.Text.MessageReceived += OnChatMessageReceived;
		}

		private void OnChatMessageReceived(TextMessage message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!message.Message.StartsWith("[UNLIMITED_MAGES]") || (Object)(object)ConfigManager.Instance == (Object)null)
			{
				return;
			}
			string[] array = message.Message.Split(':');
			if (array.Length < 1)
			{
				return;
			}
			string text = array[0];
			if (!(text == "[UNLIMITED_MAGES]REQUEST_CONFIG"))
			{
				if (text == "[UNLIMITED_MAGES]SET_TEAM_SIZE" && !ConfigManager.Instance.IsConfigReady && array.Length > 1 && int.TryParse(array[1], out var result))
				{
					ManualLogSource? log = UnlimitedMagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"[Client] Received team size from host: {result}. Finalizing config.");
					}
					ConfigManager.Instance.FinalizeConfig(result);
				}
			}
			else if (IsHost())
			{
				int teamSize = ConfigManager.Instance.TeamSize;
				ManualLogSource? log2 = UnlimitedMagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[Host] Received config request. Sending team size: {teamSize}");
				}
				BroadcastTeamSize(teamSize);
			}
		}

		private void RequestConfigFromHost()
		{
			if (!((Object)(object)_comms == (Object)null) && _comms.IsNetworkInitialized)
			{
				_comms.Text.Send("Global", "[UNLIMITED_MAGES]REQUEST_CONFIG");
			}
		}

		public void SetAndBroadcastTeamSize(int newSize)
		{
			if (IsHost() && !((Object)(object)ConfigManager.Instance == (Object)null))
			{
				ConfigManager.Instance.FinalizeConfig(newSize);
				BroadcastTeamSize(newSize);
			}
		}

		private void BroadcastTeamSize(int size)
		{
			if (!((Object)(object)_comms == (Object)null) && _comms.IsNetworkInitialized && IsHost())
			{
				string text = string.Format("{0}SET_TEAM_SIZE:{1}", "[UNLIMITED_MAGES]", size);
				_comms.Text.Send("Global", text);
				ManualLogSource? log = UnlimitedMagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[Host] Broadcasting team size: {size}");
				}
			}
		}

		private bool IsHost()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (BootstrapManager.CurrentLobbyID != 0L)
			{
				return SteamMatchmaking.GetLobbyOwner(new CSteamID(BootstrapManager.CurrentLobbyID)) == SteamUser.GetSteamID();
			}
			return false;
		}
	}
}
namespace UnlimitedMages.Components
{
	internal static class ComponentActivator
	{
		public static void Inject(ManualLogSource log)
		{
			log.LogInfo((object)"--- Injecting Mod Components onto BootstrapManager ---");
			GameObject gameObject = ((Component)BootstrapManager.instance).gameObject;
			List<Type> list = (from t in Assembly.GetExecutingAssembly().GetTypes()
				where typeof(IModComponent).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract
				select t).ToList();
			log.LogInfo((object)$"Found {list.Count} component(s) to inject.");
			foreach (Type item in list)
			{
				if (!((Object)(object)gameObject.GetComponent(item) != (Object)null))
				{
					(gameObject.AddComponent(item) as IModComponent)?.Initialize(log);
					log.LogInfo((object)("Successfully injected component: " + item.Name));
				}
			}
		}
	}
	internal interface IModComponent
	{
		void Initialize(ManualLogSource log);
	}
}
namespace UnlimitedMages.API
{
	public static class UnlimitedMagesAPI
	{
		public static bool IsReady
		{
			get
			{
				if ((Object)(object)ConfigManager.Instance != (Object)null)
				{
					return ConfigManager.Instance.IsConfigReady;
				}
				return false;
			}
		}

		public static int TeamSize => ConfigManager.Instance?.TeamSize ?? 4;

		public static event Action<int>? OnConfigReady;

		internal static void RaiseConfigReady(int teamSize)
		{
			UnlimitedMagesAPI.OnConfigReady?.Invoke(teamSize);
		}
	}
}