Decompiled source of LobbyList v0.0.1

BepInEx/plugins/com.keklick1337.peak.LobbyList.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.TextCore;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.keklick1337.peak.LobbyList")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1+333878c19e807ed11ef38d82bc85509d55af638c")]
[assembly: AssemblyProduct("com.keklick1337.peak.LobbyList")]
[assembly: AssemblyTitle("Peak Lobby List")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace LobbyList
{
	public class LobbyInfo
	{
		public string Name { get; set; } = string.Empty;


		public int PlayerCount { get; set; }

		public int MaxPlayers { get; set; }

		public string Region { get; set; } = string.Empty;


		public CSteamID? SteamLobbyId { get; set; }

		public bool IsFromSteam { get; set; }
	}
	public class LobbyListPage : MenuWindow, IHaveParentPage
	{
		private GameObject? scrollableArea;

		private Transform? lobbyContentParent;

		private readonly List<GameObject> spawnedLobbyItems = new List<GameObject>();

		private GameObject? backButton;

		private GameObject? refreshButton;

		private GameObject? titleText;

		private List<LobbyInfo> availableLobbies = new List<LobbyInfo>();

		private LobbyNetworkManager? networkManager;

		private float lastRefreshTime;

		private readonly float REFRESH_INTERVAL = 30f;

		public override bool openOnStart => false;

		public override bool selectOnOpen => true;

		public override bool closeOnPause => true;

		public override bool closeOnUICancel => true;

		public override bool blocksPlayerInput => true;

		public override bool showCursorWhileOpen => true;

		public override void Start()
		{
			((MenuWindow)this).StartClosed();
			Debug.Log((object)"[LobbyList] LobbyListPage started in closed state");
		}

		public override void Initialize()
		{
			((MenuWindow)this).Initialize();
			Debug.Log((object)"[LobbyList] LobbyListPage.Initialize called");
			if ((Object)(object)networkManager == (Object)null)
			{
				GameObject val = GameObject.Find("LobbyNetworkManager");
				if ((Object)(object)val != (Object)null)
				{
					networkManager = val.GetComponent<LobbyNetworkManager>();
				}
			}
			CreateUI();
		}

		public override void OnOpen()
		{
			((MenuWindow)this).OnOpen();
			Debug.Log((object)"[LobbyList] LobbyListPage.OnOpen called");
			LobbyNetworkManager.OnSteamLobbiesUpdated -= OnSteamLobbiesUpdated;
			LobbyNetworkManager.OnSteamLobbiesUpdated += OnSteamLobbiesUpdated;
			Debug.Log((object)"[LobbyList] Subscribed to OnSteamLobbiesUpdated event");
			RefreshLobbyList();
			lastRefreshTime = Time.time;
		}

		public override void OnClose()
		{
			((MenuWindow)this).OnClose();
			Debug.Log((object)"[LobbyList] LobbyListPage.OnClose called");
			LobbyNetworkManager.OnSteamLobbiesUpdated -= OnSteamLobbiesUpdated;
			Debug.Log((object)"[LobbyList] Unsubscribed from OnSteamLobbiesUpdated event");
			networkManager?.StopSearchingForRooms();
		}

		private void CreateUI()
		{
			Debug.Log((object)"[LobbyList] Creating LobbyListPage UI using PeakUIHelpers...");
			CreateBackground();
			CreateTitle();
			CreateScrollArea();
			CreateControlButtons();
			Debug.Log((object)"[LobbyList] LobbyListPage UI created successfully using game styles!");
		}

		private void CreateBackground()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Background");
			val.transform.SetParent(((Component)this).transform, false);
			RectTransform rectTransform = val.AddComponent<RectTransform>();
			Image val2 = val.AddComponent<Image>();
			PeakUIHelpers.ExpandToParent(rectTransform);
			((Graphic)val2).color = new Color(0f, 0f, 0f, 0.9f);
		}

		private void CreateTitle()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			titleText = PeakUIHelpers.CreateGameText("Available Game Lobbies", ((Component)this).transform, "TitleText", useBold: false);
			RectTransform component = titleText.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0.85f);
			component.anchorMax = new Vector2(1f, 0.95f);
			component.offsetMin = new Vector2(50f, 0f);
			component.offsetMax = new Vector2(-50f, 0f);
			TextMeshProUGUI component2 = titleText.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).fontSize = 32f;
			((TMP_Text)component2).fontStyle = (FontStyles)0;
			((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
		}

		private void CreateScrollArea()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			scrollableArea = PeakUIHelpers.CreateScrollableArea(((Component)this).transform);
			RectTransform component = scrollableArea.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.1f, 0.15f);
			component.anchorMax = new Vector2(0.9f, 0.8f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			Transform val = scrollableArea.transform.Find("Viewport");
			if ((Object)(object)val != (Object)null)
			{
				lobbyContentParent = val.Find("Content");
				if ((Object)(object)lobbyContentParent != (Object)null)
				{
					Debug.Log((object)"[LobbyList] Found Content in scrollable area structure");
				}
				else
				{
					Debug.LogError((object)"[LobbyList] Could not find Content in Viewport!");
				}
			}
			else
			{
				Debug.LogError((object)"[LobbyList] Could not find Viewport in scrollable area!");
			}
		}

		private void CreateControlButtons()
		{
			//IL_00e7: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			Debug.Log((object)"[LobbyList] Creating control buttons using PeakUIHelpers...");
			backButton = PeakUIHelpers.CreateGameStyleButton("Back", ((Component)this).transform);
			if ((Object)(object)backButton != (Object)null)
			{
				RectTransform component = backButton.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.05f, 0.05f);
				component.anchorMax = new Vector2(0.05f, 0.05f);
				component.anchoredPosition = new Vector2(100f, 40f);
				component.sizeDelta = new Vector2(180f, 70f);
				Button button = PeakUIHelpers.GetButton(backButton);
				if (button != null)
				{
					((UnityEvent)button.onClick).AddListener(new UnityAction(GoBack));
				}
			}
			Color value = default(Color);
			((Color)(ref value))..ctor(0.2f, 0.4f, 0.8f, 0.8f);
			refreshButton = PeakUIHelpers.CreateGameStyleButton("Refresh", ((Component)this).transform, value);
			if ((Object)(object)refreshButton != (Object)null)
			{
				RectTransform component2 = refreshButton.GetComponent<RectTransform>();
				component2.anchorMin = new Vector2(0.95f, 0.05f);
				component2.anchorMax = new Vector2(0.95f, 0.05f);
				component2.anchoredPosition = new Vector2(-100f, 40f);
				component2.sizeDelta = new Vector2(180f, 70f);
				Button button2 = PeakUIHelpers.GetButton(refreshButton);
				if (button2 != null)
				{
					((UnityEvent)button2.onClick).AddListener(new UnityAction(RefreshLobbyList));
				}
			}
			Debug.Log((object)"[LobbyList] Control buttons created using game style templates");
		}

		private void RefreshLobbyList()
		{
			float num = Time.time - lastRefreshTime;
			if (num < 2f)
			{
				Debug.Log((object)$"[LobbyList] Skipping refresh - too soon since last refresh ({num:F1}s ago)");
				return;
			}
			lastRefreshTime = Time.time;
			Plugin.Log.LogInfo((object)"Refreshing lobby list...");
			Debug.Log((object)"[LobbyList] Refreshing lobby list...");
			if ((Object)(object)lobbyContentParent == (Object)null)
			{
				Debug.LogError((object)"[LobbyList] Cannot refresh - lobby content parent is null");
			}
			else if ((Object)(object)networkManager != (Object)null)
			{
				Debug.Log((object)"[LobbyList] Network manager found, requesting Steam lobbies...");
				networkManager.RequestSteamLobbies();
				Debug.Log((object)"[LobbyList] Steam lobby request sent");
			}
			else
			{
				Debug.LogWarning((object)"[LobbyList] Network manager is null, showing no connection message");
				ClearLobbyItems();
				ShowNoConnectionMessage();
			}
		}

		private void ClearLobbyItems()
		{
			foreach (GameObject spawnedLobbyItem in spawnedLobbyItems)
			{
				if ((Object)(object)spawnedLobbyItem != (Object)null)
				{
					Object.Destroy((Object)(object)spawnedLobbyItem);
				}
			}
			spawnedLobbyItems.Clear();
			availableLobbies.Clear();
		}

		private void CreateLobbyItem(LobbyInfo lobbyInfo)
		{
			//IL_004a: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			LobbyInfo lobbyInfo2 = lobbyInfo;
			if ((Object)(object)lobbyContentParent == (Object)null)
			{
				Debug.LogError((object)"[LobbyList] Content parent not found!");
				return;
			}
			(Color color, bool canConnect, string lobbyType) lobbyTypeAndColor = GetLobbyTypeAndColor(lobbyInfo2.Name, lobbyInfo2.SteamLobbyId);
			Color item = lobbyTypeAndColor.color;
			bool item2 = lobbyTypeAndColor.canConnect;
			string item3 = lobbyTypeAndColor.lobbyType;
			GameObject val = PeakUIHelpers.CreateLobbyItemButton(lobbyInfo2.Name, lobbyContentParent, item);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"[LobbyList] Could not create lobby button, falling back to simple item");
				CreateSimpleLobbyItem(lobbyInfo2);
				return;
			}
			((Object)val).name = "LobbyItem_" + lobbyInfo2.Name;
			Button button = PeakUIHelpers.GetButton(val);
			if ((Object)(object)button != (Object)null)
			{
				((UnityEventBase)button.onClick).RemoveAllListeners();
				TextMeshProUGUI buttonText = PeakUIHelpers.GetButtonText(val);
				if ((Object)(object)buttonText != (Object)null)
				{
					((TMP_Text)buttonText).textWrappingMode = (TextWrappingModes)0;
					((TMP_Text)buttonText).overflowMode = (TextOverflowModes)1;
					((TMP_Text)buttonText).fontSize = 16f;
					((TMP_Text)buttonText).alignment = (TextAlignmentOptions)514;
					if (lobbyInfo2.SteamLobbyId.HasValue)
					{
						if (!item2)
						{
							((TMP_Text)buttonText).text = $"<color=red>{item3}</color> {lobbyInfo2.Name} - <color=red>Game in progress</color> - Players: {lobbyInfo2.PlayerCount}/{lobbyInfo2.MaxPlayers}";
							((Selectable)button).interactable = false;
						}
						else if (item3 == "[LOBBY]")
						{
							((TMP_Text)buttonText).text = $"<color=green>{item3}</color> {lobbyInfo2.Name} - <color=green>Players: {lobbyInfo2.PlayerCount}/{lobbyInfo2.MaxPlayers}</color> - Region: {lobbyInfo2.Region}";
							((UnityEvent)button.onClick).AddListener((UnityAction)delegate
							{
								//IL_0014: Unknown result type (might be due to invalid IL or missing references)
								JoinSteamLobby(lobbyInfo2.SteamLobbyId.Value.m_SteamID);
							});
						}
						else
						{
							((TMP_Text)buttonText).text = $"<color=yellow>{item3}</color> {lobbyInfo2.Name} - <color=green>Players: {lobbyInfo2.PlayerCount}/{lobbyInfo2.MaxPlayers}</color> - Region: {lobbyInfo2.Region}";
							((UnityEvent)button.onClick).AddListener((UnityAction)delegate
							{
								//IL_0014: Unknown result type (might be due to invalid IL or missing references)
								JoinSteamLobby(lobbyInfo2.SteamLobbyId.Value.m_SteamID);
							});
						}
					}
					else
					{
						((TMP_Text)buttonText).text = "<color=gray>[INFO]</color> " + lobbyInfo2.Name;
						((Selectable)button).interactable = false;
					}
					Debug.Log((object)$"[LobbyList] Updated lobby text using game font - Type: {item3}, CanConnect: {item2}");
				}
			}
			spawnedLobbyItems.Add(val);
			Debug.Log((object)$"[LobbyList] Created lobby item using PeakUI: {lobbyInfo2.Name} (Type: {item3}, CanConnect: {item2})");
		}

		private void CreateSimpleLobbyItem(LobbyInfo lobbyInfo)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			LobbyInfo lobbyInfo2 = lobbyInfo;
			Debug.LogWarning((object)"[LobbyList] Creating fallback simple lobby item");
			GameObject val = new GameObject("LobbyItem_" + lobbyInfo2.Name);
			val.transform.SetParent(lobbyContentParent, false);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredHeight = 70f;
			val2.flexibleWidth = 1f;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.15f, 0.15f, 0.15f, 0.9f);
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = PeakUIHelpers.CreateGameText("", val.transform, "FallbackText");
			TextMeshProUGUI component = val5.GetComponent<TextMeshProUGUI>();
			RectTransform component2 = val5.GetComponent<RectTransform>();
			PeakUIHelpers.ExpandToParent(component2);
			component2.offsetMin = new Vector2(20f, 5f);
			component2.offsetMax = new Vector2(-20f, -5f);
			((TMP_Text)component).fontSize = 14f;
			((TMP_Text)component).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)component).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)component).overflowMode = (TextOverflowModes)1;
			if (lobbyInfo2.SteamLobbyId.HasValue)
			{
				((TMP_Text)component).text = $"<color=yellow>[STEAM]</color> {lobbyInfo2.Name} - <color=green>Players: {lobbyInfo2.PlayerCount}/{lobbyInfo2.MaxPlayers}</color> - Region: {lobbyInfo2.Region}";
				((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
				{
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					JoinSteamLobby(lobbyInfo2.SteamLobbyId.Value.m_SteamID);
				});
			}
			else
			{
				((TMP_Text)component).text = "<color=gray>[INFO]</color> " + lobbyInfo2.Name;
				((Selectable)val4).interactable = false;
			}
			spawnedLobbyItems.Add(val);
			Debug.Log((object)("[LobbyList] Created fallback simple lobby item: " + lobbyInfo2.Name));
		}

		private void ShowNoConnectionMessage()
		{
			LobbyInfo lobbyInfo = new LobbyInfo
			{
				Name = "Not connected to game network. Please start or join a game first.",
				PlayerCount = 0,
				MaxPlayers = 0,
				Region = "",
				SteamLobbyId = null
			};
			availableLobbies.Add(lobbyInfo);
			CreateLobbyItem(lobbyInfo);
		}

		private void JoinSteamLobby(ulong steamLobbyId)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)$"Attempting to join Steam lobby: {steamLobbyId}");
			Debug.Log((object)$"[LobbyList] Attempting to join Steam lobby: {steamLobbyId}");
			try
			{
				SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
				if (service != null)
				{
					Debug.Log((object)"[LobbyList] Using SteamLobbyHandler.TryJoinLobby");
					CSteamID val = default(CSteamID);
					((CSteamID)(ref val))..ctor(steamLobbyId);
					service.TryJoinLobby(val);
					Debug.Log((object)$"[LobbyList] Steam lobby join request sent: {steamLobbyId}");
					Plugin.Log.LogInfo((object)$"Steam lobby join request sent via TryJoinLobby: {steamLobbyId}");
					GoBack();
				}
				else
				{
					Debug.LogError((object)"[LobbyList] SteamLobbyHandler service not found!");
					Plugin.Log.LogError((object)"SteamLobbyHandler service not found - cannot join Steam lobby");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[LobbyList] Error joining Steam lobby: " + ex.Message));
				Plugin.Log.LogError((object)("Error joining Steam lobby: " + ex.Message));
			}
		}

		private void GoBack()
		{
			Debug.Log((object)"[LobbyList] Going back - closing MenuWindow");
			((MenuWindow)this).Close();
		}

		private void OnSteamLobbiesUpdated(List<LobbyInfo> steamLobbies)
		{
			Debug.Log((object)$"[LobbyList] OnSteamLobbiesUpdated called with {steamLobbies?.Count ?? 0} Steam lobbies");
			if (!((MenuWindow)this).isOpen || (Object)(object)lobbyContentParent == (Object)null)
			{
				Debug.Log((object)$"[LobbyList] Skipping lobby update - window closed or UI not ready. isOpen: {((MenuWindow)this).isOpen}, lobbyContentParent: {(Object)(object)lobbyContentParent != (Object)null}");
				return;
			}
			if (steamLobbies == null)
			{
				Debug.LogWarning((object)"[LobbyList] OnSteamLobbiesUpdated received null lobby list");
				return;
			}
			if (spawnedLobbyItems.Count == 0 || Mathf.Abs(steamLobbies.Count - spawnedLobbyItems.Count) > steamLobbies.Count / 2)
			{
				Debug.Log((object)"[LobbyList] Clearing all lobby items for full refresh");
				ClearLobbyItems();
				foreach (LobbyInfo steamLobby2 in steamLobbies)
				{
					availableLobbies.Add(steamLobby2);
					CreateLobbyItem(steamLobby2);
					Debug.Log((object)("[LobbyList] Added Steam lobby: " + steamLobby2.Name));
				}
			}
			else
			{
				Debug.Log((object)"[LobbyList] Performing incremental update");
				foreach (LobbyInfo steamLobby in steamLobbies)
				{
					if (!availableLobbies.Any((LobbyInfo existing) => existing.SteamLobbyId.HasValue && steamLobby.SteamLobbyId.HasValue && existing.SteamLobbyId.Value.m_SteamID == steamLobby.SteamLobbyId.Value.m_SteamID))
					{
						availableLobbies.Add(steamLobby);
						CreateLobbyItem(steamLobby);
						Debug.Log((object)("[LobbyList] Added new Steam lobby: " + steamLobby.Name));
					}
				}
			}
			if (steamLobbies.Count == 0 && spawnedLobbyItems.Count == 0)
			{
				ShowNoConnectionMessage();
			}
			Debug.Log((object)$"[LobbyList] Finished updating lobby UI - total items: {spawnedLobbyItems.Count}");
		}

		public override void Update()
		{
			((MenuWindow)this).Update();
			if (((MenuWindow)this).isOpen && Time.time - lastRefreshTime >= REFRESH_INTERVAL)
			{
				Debug.Log((object)"[LobbyList] Auto-refreshing lobby list after 30 seconds");
				RefreshLobbyList();
				lastRefreshTime = Time.time;
			}
		}

		public (UIPage, PageTransistion) GetParentPage()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			MainMenuMainPage val = Object.FindFirstObjectByType<MainMenuMainPage>();
			if ((Object)(object)val != (Object)null)
			{
				return ((UIPage)(object)val, (PageTransistion)new SetActivePageTransistion());
			}
			UIPage item = new GameObject("EmptyPage").AddComponent<UIPage>();
			return (item, (PageTransistion)new SetActivePageTransistion());
		}

		public void SetNetworkManager(LobbyNetworkManager manager)
		{
			networkManager = manager;
		}

		private (Color color, bool canConnect, string lobbyType) GetLobbyTypeAndColor(string lobbyName, CSteamID? steamLobbyId = null)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			if (steamLobbyId.HasValue)
			{
				try
				{
					string lobbyData = SteamMatchmaking.GetLobbyData(steamLobbyId.Value, "ModListHash");
					string lobbyData2 = SteamMatchmaking.GetLobbyData(steamLobbyId.Value, "ModList");
					string lobbyData3 = SteamMatchmaking.GetLobbyData(steamLobbyId.Value, "HasLobbyListMod");
					ModCompatibilityResult modCompatibilityResult = ModCompatibilitySystem.CheckCompatibility(lobbyData, lobbyData2);
					switch (modCompatibilityResult.CompatibilityType)
					{
					case CompatibilityType.Perfect:
						return (new Color(0.2f, 0.8f, 0.2f, 0.8f), true, "PERFECT");
					case CompatibilityType.Compatible:
						return (new Color(0.4f, 0.6f, 0.2f, 0.8f), true, "COMPAT");
					case CompatibilityType.Vanilla:
						return (new Color(0.6f, 0.6f, 0.3f, 0.6f), true, "VANILLA");
					case CompatibilityType.IncompatibleMods:
					case CompatibilityType.MissingCriticalMods:
						return (new Color(0.7f, 0.2f, 0.2f, 0.6f), true, "INCOMP");
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error checking mod compatibility: " + ex.Message));
				}
			}
			if (Regex.IsMatch(lobbyName, "Level_\\d+", RegexOptions.IgnoreCase))
			{
				Color item = default(Color);
				((Color)(ref item))..ctor(0.3f, 0.3f, 0.3f, 0.6f);
				return (item, false, "IN GAME");
			}
			if (lobbyName.ToLower().Contains("airport"))
			{
				Color item2 = default(Color);
				((Color)(ref item2))..ctor(0.2f, 0.6f, 0.2f, 0.8f);
				return (item2, true, "LOBBY");
			}
			Color item3 = default(Color);
			((Color)(ref item3))..ctor(0.4f, 0.4f, 0.4f, 0.8f);
			return (item3, true, "STEAM");
		}
	}
	public static class LobbyListUI_Native
	{
		private static LobbyNetworkManager? networkManager;

		private static LobbyListPage? lobbyListPage;

		public static void Initialize()
		{
			try
			{
				Plugin.Log.LogInfo((object)"Starting native LobbyListUI initialization...");
				Debug.Log((object)"[LobbyList] Starting native LobbyListUI initialization...");
				CreateNetworkManager();
				CreateLobbyListPage();
				Plugin.Log.LogInfo((object)"Native LobbyListUI initialized successfully! Find Game button will be created via hook.");
				Debug.Log((object)"[LobbyList] Native LobbyListUI initialized successfully! Find Game button will be created via hook.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to initialize native LobbyListUI: " + ex.Message));
				Debug.Log((object)("[LobbyList] Failed to initialize native LobbyListUI: " + ex.Message));
			}
		}

		private static void CreateNetworkManager()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Debug.Log((object)"[LobbyList] Creating network manager object...");
			if (PhotonNetwork.IsConnected)
			{
				Debug.Log((object)"[LobbyList] Game is already connected to Photon Network");
			}
			GameObject val = new GameObject("LobbyNetworkManager");
			networkManager = val.AddComponent<LobbyNetworkManager>();
			Object.DontDestroyOnLoad((Object)(object)val);
			Debug.Log((object)"[LobbyList] Network manager created successfully!");
		}

		private static void CreateLobbyListPage()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_004d: 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_006a: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			Debug.Log((object)"[LobbyList] Creating LobbyListPage as MenuWindow...");
			GameObject val = new GameObject("LobbyListCanvas");
			Object.DontDestroyOnLoad((Object)(object)val);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 1000;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			GraphicRaycaster val4 = val.AddComponent<GraphicRaycaster>();
			GameObject val5 = new GameObject("LobbyListPage");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Image val7 = val5.AddComponent<Image>();
			((Graphic)val7).color = new Color(0f, 0f, 0f, 0.8f);
			lobbyListPage = val5.AddComponent<LobbyListPage>();
			if ((Object)(object)networkManager != (Object)null)
			{
				lobbyListPage.SetNetworkManager(networkManager);
			}
			Debug.Log((object)"[LobbyList] LobbyListPage MenuWindow created with own Canvas!");
		}

		public static void ShowLobbyPage()
		{
			Plugin.Log.LogInfo((object)"Find Game button clicked - opening LobbyListPage MenuWindow!");
			Debug.Log((object)"[LobbyList] Find Game button clicked - opening LobbyListPage MenuWindow!");
			if ((Object)(object)lobbyListPage == (Object)null)
			{
				Debug.LogError((object)"[LobbyList] LobbyListPage not created!");
				return;
			}
			((MenuWindow)lobbyListPage).Open();
			Debug.Log((object)"[LobbyList] LobbyListPage MenuWindow opened!");
		}

		public static void Update()
		{
		}

		public static void RecreateButton()
		{
			Debug.Log((object)"[LobbyList] RecreateButton called - Find Game button now created automatically via MainMenuHooks");
			MainMenuMainPage val = Object.FindFirstObjectByType<MainMenuMainPage>();
			if ((Object)(object)val != (Object)null)
			{
				Transform[] array = (from t in ((Component)val).GetComponentsInChildren<Transform>(true)
					where ((Object)t).name == "FindGameButton"
					select t).ToArray();
				if (array.Length == 0)
				{
					Debug.Log((object)"[LobbyList] No Find Game button found, triggering manual creation via hook logic");
					MainMenuHooks.MainMenuMainPage_Start_Postfix(val);
				}
				else
				{
					Debug.Log((object)$"[LobbyList] Find Game button already exists ({array.Length})");
				}
			}
		}
	}
	public static class LobbyModPatches
	{
		[HarmonyPatch(typeof(SteamLobbyHandler), "CreateLobby")]
		public class CreateLobbyPatch
		{
			[CompilerGenerated]
			private sealed class <SetLobbyModDataCoroutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <SetLobbyModDataCoroutine>d__2(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0027: Expected O, but got Unknown
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0048: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSeconds(1f);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						try
						{
							string text = ModCompatibilitySystem.GenerateModHash();
							string text2 = ModCompatibilitySystem.GenerateModListString();
							CSteamID steamID = SteamUser.GetSteamID();
							Debug.Log((object)$"[LobbyList] Setting mod data for created lobby - Hash: {text.Substring(0, 8)}..., Mods: {ModCompatibilitySystem.GetInstalledMods().Count}");
							Plugin.Log.LogInfo((object)"Added mod compatibility info to created lobby");
						}
						catch (Exception ex)
						{
							Debug.LogError((object)("[LobbyList] Error in delayed lobby setup: " + ex.Message));
						}
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private static void Postfix(SteamLobbyHandler __instance)
			{
				try
				{
					SetLobbyModDataDelayed();
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error setting up lobby mod info: " + ex.Message));
				}
			}

			private static void SetLobbyModDataDelayed()
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(SetLobbyModDataCoroutine());
			}

			[IteratorStateMachine(typeof(<SetLobbyModDataCoroutine>d__2))]
			private static IEnumerator SetLobbyModDataCoroutine()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <SetLobbyModDataCoroutine>d__2(0);
			}
		}

		[HarmonyPatch(typeof(SteamLobbyHandler), "TryJoinLobby")]
		public class TryJoinLobbyPatch
		{
			private static bool Prefix(SteamLobbyHandler __instance, CSteamID lobbyId)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					string lobbyData = SteamMatchmaking.GetLobbyData(lobbyId, "ModListHash");
					string lobbyData2 = SteamMatchmaking.GetLobbyData(lobbyId, "ModList");
					string lobbyData3 = SteamMatchmaking.GetLobbyData(lobbyId, "HasLobbyListMod");
					ModCompatibilityResult modCompatibilityResult = ModCompatibilitySystem.CheckCompatibility(lobbyData, lobbyData2);
					Debug.Log((object)$"[LobbyList] Lobby compatibility check: {modCompatibilityResult.CompatibilityType} - {modCompatibilityResult.Message}");
					if (!modCompatibilityResult.RecommendConnect)
					{
						string text = modCompatibilityResult.CompatibilityType switch
						{
							CompatibilityType.Vanilla => "Cannot join vanilla lobby with mods installed", 
							CompatibilityType.IncompatibleMods => "Incompatible mods detected", 
							CompatibilityType.MissingCriticalMods => "Missing required mods: " + modCompatibilityResult.Message, 
							_ => "Mod compatibility issue", 
						};
						Debug.LogWarning((object)("[LobbyList] Blocking lobby join: " + text));
						Plugin.Log.LogWarning((object)("Blocked lobby join due to mod incompatibility: " + text));
						ShowCompatibilityWarning(text);
						return false;
					}
					Plugin.Log.LogInfo((object)$"Allowing lobby join - Compatibility: {modCompatibilityResult.CompatibilityType}");
					return true;
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error checking lobby compatibility: " + ex.Message));
					return true;
				}
			}

			private static void ShowCompatibilityWarning(string reason)
			{
				try
				{
					Debug.Log((object)("[LobbyList] Compatibility Warning: " + reason));
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error showing compatibility warning: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(SteamLobbyHandler), "OnLobbyEntered")]
		public class OnLobbyEnteredPatch
		{
			private static void Postfix(SteamLobbyHandler __instance, LobbyEnter_t param)
			{
				//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_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					uint eChatRoomEnterResponse = param.m_EChatRoomEnterResponse;
					ulong ulSteamIDLobby = param.m_ulSteamIDLobby;
					if (eChatRoomEnterResponse == 1)
					{
						CSteamID val = default(CSteamID);
						((CSteamID)(ref val))..ctor(ulSteamIDLobby);
						string lobbyData = SteamMatchmaking.GetLobbyData(val, "ModListHash");
						string lobbyData2 = SteamMatchmaking.GetLobbyData(val, "HasLobbyListMod");
						if (!string.IsNullOrEmpty(lobbyData))
						{
							string text = ModCompatibilitySystem.GenerateModHash();
							bool flag = lobbyData == text;
							Debug.Log((object)("[LobbyList] Entered lobby with mod compatibility: " + (flag ? "Perfect Match" : "Partial Compatibility")));
							Plugin.Log.LogInfo((object)$"Successfully joined modded lobby - Perfect match: {flag}");
						}
						else if (lobbyData2 == "true")
						{
							Debug.Log((object)"[LobbyList] Entered lobby with LobbyList mod but no hash");
						}
						else
						{
							Debug.Log((object)"[LobbyList] Entered vanilla lobby");
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error in OnLobbyEntered patch: " + ex.Message));
				}
			}
		}
	}
	public class LobbyNetworkManager : MonoBehaviourPunCallbacks, ILobbyCallbacks
	{
		private static LobbyNetworkManager? instance;

		private List<RoomInfo> cachedRoomList = new List<RoomInfo>();

		private List<LobbyInfo> cachedSteamLobbies = new List<LobbyInfo>();

		private bool isSearchingForRooms;

		private SteamLobbyFinder? steamLobbyFinder;

		public static LobbyNetworkManager? Instance => instance;

		public static event Action<List<LobbyInfo>>? OnRoomListChanged;

		public static event Action<List<LobbyInfo>>? OnSteamLobbiesUpdated;

		public static event Action<Room>? OnRoomJoined;

		public static event Action<string>? OnRoomJoinFailed;

		public static event Action<Room>? OnRoomCreated;

		public static event Action<string>? OnRoomCreationFailed;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				PhotonNetwork.AddCallbackTarget((object)this);
				steamLobbyFinder = ((Component)this).gameObject.AddComponent<SteamLobbyFinder>();
				SteamLobbyFinder.OnSteamLobbiesFound += OnSteamLobbiesFound;
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void OnDestroy()
		{
			if (PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
			}
			SteamLobbyFinder.OnSteamLobbiesFound -= OnSteamLobbiesFound;
		}

		public void StartSearchingForRooms()
		{
			Plugin.Log.LogInfo((object)"Starting search for rooms...");
			Debug.Log((object)"[LobbyList] Starting search for rooms...");
			Debug.Log((object)$"[LobbyList] PhotonNetwork.IsConnected: {PhotonNetwork.IsConnected}");
			Debug.Log((object)$"[LobbyList] PhotonNetwork.IsConnectedAndReady: {PhotonNetwork.IsConnectedAndReady}");
			Debug.Log((object)$"[LobbyList] PhotonNetwork.InLobby: {PhotonNetwork.InLobby}");
			isSearchingForRooms = true;
			if (!PhotonNetwork.IsConnectedAndReady)
			{
				Plugin.Log.LogWarning((object)"Not connected to Photon Network!");
				Debug.Log((object)"[LobbyList] Not connected to Photon Network!");
				List<RoomInfo> photonRooms = new List<RoomInfo>();
				LobbyNetworkManager.OnRoomListChanged?.Invoke(ConvertPhotonRoomsToLobbyInfo(photonRooms));
			}
			else if (!PhotonNetwork.InLobby)
			{
				Plugin.Log.LogInfo((object)"Joining default lobby...");
				Debug.Log((object)"[LobbyList] Joining default lobby...");
				PhotonNetwork.JoinLobby();
			}
			else
			{
				Plugin.Log.LogInfo((object)"Already in lobby, triggering room list update...");
				Debug.Log((object)"[LobbyList] Already in lobby, triggering room list update...");
				LobbyNetworkManager.OnRoomListChanged?.Invoke(ConvertPhotonRoomsToLobbyInfo(GetAvailableRooms()));
			}
		}

		public void StopSearchingForRooms()
		{
			Plugin.Log.LogInfo((object)"Stopping search for rooms...");
			isSearchingForRooms = false;
			if (PhotonNetwork.InLobby)
			{
				PhotonNetwork.LeaveLobby();
			}
		}

		public List<RoomInfo> GetAvailableRooms()
		{
			return new List<RoomInfo>(cachedRoomList);
		}

		public void JoinSpecificRoom(string roomName)
		{
			Plugin.Log.LogInfo((object)("Attempting to join room: " + roomName));
			if (!PhotonNetwork.IsConnectedAndReady)
			{
				Plugin.Log.LogError((object)"Cannot join room - not connected to Photon Network!");
				return;
			}
			if (PhotonNetwork.InLobby)
			{
				PhotonNetwork.LeaveLobby();
			}
			PhotonNetwork.JoinRoom(roomName, (string[])null);
		}

		public void CreateRoom(string roomName, int maxPlayers = 4)
		{
			//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_0060: 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_006f: Expected O, but got Unknown
			Plugin.Log.LogInfo((object)$"Creating room: {roomName} with max {maxPlayers} players");
			if (!PhotonNetwork.IsConnectedAndReady)
			{
				Plugin.Log.LogError((object)"Cannot create room - not connected to Photon Network!");
				LobbyNetworkManager.OnRoomCreationFailed?.Invoke("Not connected to network");
				return;
			}
			if (PhotonNetwork.InLobby)
			{
				PhotonNetwork.LeaveLobby();
			}
			RoomOptions val = new RoomOptions
			{
				MaxPlayers = (byte)maxPlayers,
				IsVisible = true,
				IsOpen = true
			};
			PhotonNetwork.CreateRoom(roomName, val, (TypedLobby)null, (string[])null);
		}

		public void RequestSteamLobbies()
		{
			Debug.Log((object)"[LobbyList] Requesting Steam lobbies...");
			if ((Object)(object)steamLobbyFinder != (Object)null)
			{
				steamLobbyFinder.RequestSteamLobbies();
			}
			else
			{
				Debug.LogError((object)"[LobbyList] SteamLobbyFinder not available!");
			}
		}

		private void OnSteamLobbiesFound(List<LobbyInfo> steamLobbies)
		{
			Debug.Log((object)$"[LobbyList] Received {steamLobbies.Count} Steam lobbies");
			cachedSteamLobbies = new List<LobbyInfo>(steamLobbies);
			LobbyNetworkManager.OnSteamLobbiesUpdated?.Invoke(steamLobbies);
		}

		public override void OnJoinedLobby()
		{
			Plugin.Log.LogInfo((object)"Joined lobby successfully!");
			Debug.Log((object)"[LobbyList] Joined lobby successfully!");
			isSearchingForRooms = true;
		}

		public override void OnLeftLobby()
		{
			Plugin.Log.LogInfo((object)"Left lobby");
			isSearchingForRooms = false;
			cachedRoomList.Clear();
		}

		public override void OnRoomListUpdate(List<RoomInfo> roomList)
		{
			Plugin.Log.LogInfo((object)$"Room list updated! Found {roomList.Count} rooms");
			Debug.Log((object)$"[LobbyList] Room list updated! Found {roomList.Count} rooms");
			Debug.Log((object)$"[LobbyList] isSearchingForRooms: {isSearchingForRooms}");
			foreach (RoomInfo room2 in roomList)
			{
				Debug.Log((object)$"[LobbyList] Room: {room2.Name}, Players: {room2.PlayerCount}/{room2.MaxPlayers}, Open: {room2.IsOpen}, Visible: {room2.IsVisible}, Removed: {room2.RemovedFromList}");
			}
			foreach (RoomInfo room in roomList)
			{
				if (room.RemovedFromList)
				{
					cachedRoomList.RemoveAll((RoomInfo r) => r.Name == room.Name);
					Plugin.Log.LogInfo((object)("Room removed: " + room.Name));
					Debug.Log((object)("[LobbyList] Room removed: " + room.Name));
					continue;
				}
				RoomInfo val = cachedRoomList.Find((RoomInfo r) => r.Name == room.Name);
				if (val != null)
				{
					cachedRoomList.Remove(val);
				}
				if (room.IsOpen && room.IsVisible && room.PlayerCount < room.MaxPlayers)
				{
					cachedRoomList.Add(room);
					Plugin.Log.LogInfo((object)$"Room updated: {room.Name} ({room.PlayerCount}/{room.MaxPlayers})");
				}
			}
			LobbyNetworkManager.OnRoomListChanged?.Invoke(ConvertPhotonRoomsToLobbyInfo(GetAvailableRooms()));
		}

		public override void OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics)
		{
			Plugin.Log.LogInfo((object)$"Lobby statistics updated: {lobbyStatistics.Count} lobbies");
		}

		public override void OnJoinedRoom()
		{
			ManualLogSource log = Plugin.Log;
			Room currentRoom = PhotonNetwork.CurrentRoom;
			log.LogInfo((object)("Successfully joined room: " + ((currentRoom != null) ? currentRoom.Name : null)));
			if (PhotonNetwork.CurrentRoom != null)
			{
				LobbyNetworkManager.OnRoomJoined?.Invoke(PhotonNetwork.CurrentRoom);
			}
		}

		public override void OnJoinRoomFailed(short returnCode, string message)
		{
			Plugin.Log.LogError((object)$"Failed to join room: {message} (Code: {returnCode})");
			LobbyNetworkManager.OnRoomJoinFailed?.Invoke(message);
		}

		public override void OnCreatedRoom()
		{
			Plugin.Log.LogInfo((object)("Successfully created room: " + PhotonNetwork.CurrentRoom.Name));
			LobbyNetworkManager.OnRoomCreated?.Invoke(PhotonNetwork.CurrentRoom);
		}

		public override void OnCreateRoomFailed(short returnCode, string message)
		{
			Plugin.Log.LogError((object)$"Failed to create room: {message} (Code: {returnCode})");
			LobbyNetworkManager.OnRoomCreationFailed?.Invoke(message);
		}

		public override void OnConnectedToMaster()
		{
			Plugin.Log.LogInfo((object)"Connected to Photon Master Server");
		}

		public override void OnDisconnected(DisconnectCause cause)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogWarning((object)$"Disconnected from Photon Network: {cause}");
			cachedRoomList.Clear();
			isSearchingForRooms = false;
		}

		private List<LobbyInfo> ConvertPhotonRoomsToLobbyInfo(List<RoomInfo> photonRooms)
		{
			List<LobbyInfo> list = new List<LobbyInfo>();
			foreach (RoomInfo photonRoom in photonRooms)
			{
				LobbyInfo item = new LobbyInfo
				{
					Name = photonRoom.Name,
					PlayerCount = photonRoom.PlayerCount,
					MaxPlayers = photonRoom.MaxPlayers,
					Region = (PhotonNetwork.CloudRegion ?? "Unknown"),
					IsFromSteam = false
				};
				list.Add(item);
			}
			return list;
		}

		public List<LobbyInfo> GetPhotonLobbies()
		{
			return ConvertPhotonRoomsToLobbyInfo(cachedRoomList);
		}

		public List<LobbyInfo> GetSteamLobbies()
		{
			return new List<LobbyInfo>(cachedSteamLobbies);
		}

		public void JoinSteamLobby(LobbyInfo lobbyInfo)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (lobbyInfo.SteamLobbyId.HasValue)
			{
				Debug.Log((object)("[LobbyList] Joining Steam lobby: " + lobbyInfo.Name));
				SteamMatchmaking.JoinLobby(lobbyInfo.SteamLobbyId.Value);
			}
			else
			{
				Debug.LogError((object)"[LobbyList] Cannot join Steam lobby - no SteamLobbyId");
			}
		}

		public void JoinPhotonLobby(LobbyInfo lobbyInfo)
		{
			Debug.Log((object)("[LobbyList] Joining Photon room: " + lobbyInfo.Name));
			PhotonNetwork.JoinRoom(lobbyInfo.Name, (string[])null);
		}

		public void RefreshLobbies()
		{
			Debug.Log((object)"[LobbyList] RefreshLobbies called");
			StartSearchingForRooms();
			RequestSteamLobbies();
		}
	}
	[HarmonyPatch]
	public static class MainMenuHooks
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<Transform, bool> <>9__1_0;

			public static UnityAction <>9__1_1;

			internal bool <CreateFindGameButton>b__1_0(Transform t)
			{
				return ((Object)t).name == "FindGameButton";
			}

			internal void <CreateFindGameButton>b__1_1()
			{
				Debug.Log((object)"[LobbyList] Find Game button clicked from hook");
				LobbyListUI_Native.ShowLobbyPage();
			}
		}

		[HarmonyPatch(typeof(MainMenuMainPage), "Start")]
		[HarmonyPostfix]
		public static void MainMenuMainPage_Start_Postfix(MainMenuMainPage __instance)
		{
			try
			{
				Debug.Log((object)"[LobbyList] MainMenuMainPage.Start hook triggered - creating Find Game button");
				CreateFindGameButton(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in MainMenuMainPage.Start hook: " + ex.Message));
				Debug.LogError((object)("[LobbyList] Error in MainMenuMainPage.Start hook: " + ex.Message));
			}
		}

		private static void CreateFindGameButton(MainMenuMainPage mainMenuPage)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			Transform[] array = (from t in ((Component)mainMenuPage).GetComponentsInChildren<Transform>(true)
				where ((Object)t).name == "FindGameButton"
				select t).ToArray();
			if (array.Length != 0)
			{
				Debug.Log((object)$"[LobbyList] Find Game button already exists ({array.Length}), skipping creation");
				return;
			}
			Debug.Log((object)"[LobbyList] Creating Find Game button using reflection...");
			Type type = ((object)mainMenuPage).GetType();
			object? obj = type.GetField("m_settingsButton", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(mainMenuPage);
			Button val = (Button)((obj is Button) ? obj : null);
			if (val != null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
				((Object)val2).name = "FindGameButton";
				TextMeshProUGUI componentInChildren = val2.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = "Find Game";
				}
				object? obj2 = type.GetField("m_playButton", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(mainMenuPage);
				Button val3 = (Button)((obj2 is Button) ? obj2 : null);
				if (val3 != null)
				{
					RectTransform component = val2.GetComponent<RectTransform>();
					RectTransform component2 = ((Component)val3).GetComponent<RectTransform>();
					component.sizeDelta = component2.sizeDelta;
					component.anchorMin = component2.anchorMin;
					component.anchorMax = component2.anchorMax;
					component.pivot = component2.pivot;
					float num = component2.anchoredPosition.y - component2.sizeDelta.y - 10f + 140f;
					component.anchoredPosition = new Vector2(component2.anchoredPosition.x, num);
				}
				Button component3 = val2.GetComponent<Button>();
				((UnityEventBase)component3.onClick).RemoveAllListeners();
				ButtonClickedEvent onClick = component3.onClick;
				object obj3 = <>c.<>9__1_1;
				if (obj3 == null)
				{
					UnityAction val4 = delegate
					{
						Debug.Log((object)"[LobbyList] Find Game button clicked from hook");
						LobbyListUI_Native.ShowLobbyPage();
					};
					<>c.<>9__1_1 = val4;
					obj3 = (object)val4;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj3);
				Plugin.Log.LogInfo((object)"Find Game button created successfully via hook!");
				Debug.Log((object)"[LobbyList] Find Game button created successfully via hook!");
			}
			else
			{
				Plugin.Log.LogError((object)"Could not find settings button field via reflection!");
				Debug.LogError((object)"[LobbyList] Could not find settings button field via reflection!");
			}
		}
	}
	public static class ModCompatibilitySystem
	{
		private static string? _cachedModHash;

		private static List<string>? _cachedModList;

		public static string GenerateModHash()
		{
			if (_cachedModHash != null)
			{
				return _cachedModHash;
			}
			List<string> installedMods = GetInstalledMods();
			string s = string.Join("|", installedMods.OrderBy((string x) => x));
			using (SHA256 sHA = SHA256.Create())
			{
				byte[] inArray = sHA.ComputeHash(Encoding.UTF8.GetBytes(s));
				_cachedModHash = Convert.ToBase64String(inArray);
			}
			Debug.Log((object)("[LobbyList] Generated mod hash: " + _cachedModHash));
			return _cachedModHash;
		}

		public static List<string> GetInstalledMods()
		{
			if (_cachedModList != null)
			{
				return _cachedModList;
			}
			_cachedModList = new List<string>();
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				string item = $"{value.Metadata.GUID}:{value.Metadata.Version}";
				_cachedModList.Add(item);
			}
			Debug.Log((object)$"[LobbyList] Found {_cachedModList.Count} installed mods");
			return _cachedModList;
		}

		public static string GenerateModListString()
		{
			List<string> installedMods = GetInstalledMods();
			return string.Join(";", installedMods);
		}

		public static ModCompatibilityResult CheckCompatibility(string? lobbyModHash, string? lobbyModList)
		{
			if (string.IsNullOrEmpty(lobbyModHash) && string.IsNullOrEmpty(lobbyModList))
			{
				return new ModCompatibilityResult
				{
					IsCompatible = false,
					CompatibilityType = CompatibilityType.Vanilla,
					Message = "Vanilla lobby (no mods)",
					RecommendConnect = false
				};
			}
			string text = GenerateModHash();
			HashSet<string> clientMods = GetInstalledMods().ToHashSet();
			if (!string.IsNullOrEmpty(lobbyModHash) && lobbyModHash == text)
			{
				return new ModCompatibilityResult
				{
					IsCompatible = true,
					CompatibilityType = CompatibilityType.Perfect,
					Message = "Perfect match",
					RecommendConnect = true
				};
			}
			if (!string.IsNullOrEmpty(lobbyModList))
			{
				HashSet<string> hashSet = lobbyModList.Split(';').ToHashSet();
				bool flag = hashSet.Any((string mod) => mod.StartsWith("com.keklick1337.peak.LobbyList"));
				bool flag2 = clientMods.Any((string mod) => mod.StartsWith("com.keklick1337.peak.LobbyList"));
				if (!flag && flag2)
				{
					return new ModCompatibilityResult
					{
						IsCompatible = false,
						CompatibilityType = CompatibilityType.IncompatibleMods,
						Message = "Host doesn't have LobbyList mod",
						RecommendConnect = false
					};
				}
				List<string> criticalMods = GetCriticalMods(hashSet);
				List<string> source = criticalMods.Where((string mod) => !clientMods.Contains(mod)).ToList();
				if (source.Any())
				{
					return new ModCompatibilityResult
					{
						IsCompatible = false,
						CompatibilityType = CompatibilityType.MissingCriticalMods,
						Message = "Missing critical mods: " + string.Join(", ", source.Take(2)),
						RecommendConnect = false
					};
				}
				return new ModCompatibilityResult
				{
					IsCompatible = true,
					CompatibilityType = CompatibilityType.Compatible,
					Message = "Compatible mods",
					RecommendConnect = true
				};
			}
			return new ModCompatibilityResult
			{
				IsCompatible = false,
				CompatibilityType = CompatibilityType.Unknown,
				Message = "Unknown compatibility",
				RecommendConnect = false
			};
		}

		private static List<string> GetCriticalMods(HashSet<string> lobbyMods)
		{
			List<string> list = new List<string>();
			foreach (string lobbyMod in lobbyMods)
			{
				if (lobbyMod.Contains("BepInEx") || lobbyMod.Contains("HarmonyLib") || lobbyMod.Contains("LobbyList") || lobbyMod.Contains("GameBalance") || lobbyMod.Contains("CoreMod"))
				{
					list.Add(lobbyMod);
				}
			}
			return list;
		}
	}
	public class ModCompatibilityResult
	{
		public bool IsCompatible { get; set; }

		public CompatibilityType CompatibilityType { get; set; }

		public string Message { get; set; } = "";


		public bool RecommendConnect { get; set; }
	}
	public enum CompatibilityType
	{
		Perfect,
		Compatible,
		Vanilla,
		IncompatibleMods,
		MissingCriticalMods,
		Unknown
	}
	public static class PeakUIHelpers
	{
		private static TMP_FontAsset? _darumaFontAsset;

		private static GameObject? _buttonTemplate;

		public static TMP_FontAsset? GetGameFont()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			if ((Object)(object)_darumaFontAsset == (Object)null)
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				_darumaFontAsset = ((IEnumerable<TMP_FontAsset>)array).FirstOrDefault((Func<TMP_FontAsset, bool>)delegate(TMP_FontAsset fontAsset)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					FaceInfo faceInfo2 = ((TMP_Asset)fontAsset).faceInfo;
					return ((FaceInfo)(ref faceInfo2)).familyName == "Daruma Drop One" || ((Object)fontAsset).name.Contains("Daruma") || ((Object)fontAsset).name.Contains("daruma");
				});
				FaceInfo faceInfo;
				if ((Object)(object)_darumaFontAsset != (Object)null)
				{
					string[] obj = new string[5]
					{
						"[LobbyList] Found game font: ",
						((Object)_darumaFontAsset).name,
						" (",
						null,
						null
					};
					faceInfo = ((TMP_Asset)_darumaFontAsset).faceInfo;
					obj[3] = ((FaceInfo)(ref faceInfo)).familyName;
					obj[4] = ")";
					Debug.Log((object)string.Concat(obj));
				}
				else
				{
					Debug.LogWarning((object)"[LobbyList] Daruma Drop One font not found, checking all available fonts...");
					TMP_FontAsset[] array2 = array;
					foreach (TMP_FontAsset val in array2)
					{
						string name = ((Object)val).name;
						faceInfo = ((TMP_Asset)val).faceInfo;
						Debug.Log((object)("[LobbyList] Available font: " + name + " - " + ((FaceInfo)(ref faceInfo)).familyName));
					}
					_darumaFontAsset = ((IEnumerable<TMP_FontAsset>)array).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset fontAsset) => (Object)(object)fontAsset != (Object)null && !string.IsNullOrEmpty(((Object)fontAsset).name)));
					if ((Object)(object)_darumaFontAsset != (Object)null)
					{
						Debug.Log((object)("[LobbyList] Using fallback font: " + ((Object)_darumaFontAsset).name));
					}
				}
			}
			return _darumaFontAsset;
		}

		public static GameObject CreateGameStyleButton(string buttonName, Transform parent, Color? customColor = null)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			GameObject buttonTemplate = GetButtonTemplate();
			if ((Object)(object)buttonTemplate != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(buttonTemplate, parent);
				((Object)val).name = buttonName;
				val.SetActive(true);
				TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = buttonName;
				}
				if (customColor.HasValue)
				{
					ApplyCustomButtonColor(val, customColor.Value);
				}
				Button component = val.GetComponent<Button>();
				if ((Object)(object)component != (Object)null)
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
				}
				Debug.Log((object)("[LobbyList] Created game style button from template: " + buttonName));
				return val;
			}
			Debug.LogWarning((object)("[LobbyList] Button template not available, creating fallback button: " + buttonName));
			return CreateFallbackButton(buttonName, parent, customColor);
		}

		private static GameObject CreateFallbackButton(string buttonName, Transform parent, Color? customColor = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00aa: 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_00d6: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_013f: 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)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: 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_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(buttonName);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Button val3 = val.AddComponent<Button>();
			GameObject val4 = new GameObject("Panel");
			val4.transform.SetParent(val.transform, false);
			RectTransform rectTransform = val4.AddComponent<RectTransform>();
			ExpandToParent(rectTransform);
			Image val5 = val4.AddComponent<Image>();
			((Graphic)val5).color = new Color(0.1792453f, 0.1253449f, 0.09046815f, 62f / 85f);
			GameObject val6 = new GameObject("Border");
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = new Vector2(0f, 1f);
			val7.anchorMax = new Vector2(1f, 1f);
			val7.sizeDelta = new Vector2(0f, 2f);
			val7.anchoredPosition = new Vector2(0f, 0f);
			Image val8 = val6.AddComponent<Image>();
			((Graphic)val8).color = Color.white;
			GameObject val9 = new GameObject("Border");
			val9.transform.SetParent(val.transform, false);
			RectTransform val10 = val9.AddComponent<RectTransform>();
			val10.anchorMin = new Vector2(0f, 0f);
			val10.anchorMax = new Vector2(1f, 0f);
			val10.sizeDelta = new Vector2(0f, 2f);
			val10.anchoredPosition = new Vector2(0f, 0f);
			Image val11 = val9.AddComponent<Image>();
			((Graphic)val11).color = Color.white;
			GameObject val12 = new GameObject("Text");
			val12.transform.SetParent(val.transform, false);
			RectTransform rectTransform2 = val12.AddComponent<RectTransform>();
			ExpandToParent(rectTransform2);
			TextMeshProUGUI val13 = val12.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset gameFont = GetGameFont();
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)val13).font = gameFont;
				Debug.Log((object)("[LobbyList] Applied game font to button text: " + ((Object)gameFont).name));
			}
			else
			{
				Debug.LogWarning((object)"[LobbyList] No game font available for button, using TMP default");
			}
			((Graphic)val13).color = Color.white;
			((TMP_Text)val13).fontSize = 22f;
			((TMP_Text)val13).fontStyle = (FontStyles)1;
			((TMP_Text)val13).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val13).text = buttonName;
			((Selectable)val3).targetGraphic = (Graphic)(object)val5;
			Color val15 = (((Graphic)val5).color = (Color)(((??)customColor) ?? new Color(0.1792453f, 0.1253449f, 0.09046815f, 62f / 85f)));
			ColorBlock colors = ((Selectable)val3).colors;
			((ColorBlock)(ref colors)).normalColor = val15;
			((ColorBlock)(ref colors)).highlightedColor = Color.Lerp(val15, Color.white, 0.2f);
			((ColorBlock)(ref colors)).pressedColor = Color.Lerp(val15, Color.black, 0.2f);
			((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
			((Selectable)val3).colors = colors;
			Debug.Log((object)("[LobbyList] Created fallback button: " + buttonName));
			return val;
		}

		public static GameObject CreateGameText(string displayText, Transform parent, string objectName = "GameText", bool useBold = true)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset gameFont = GetGameFont();
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)val3).font = gameFont;
				Debug.Log((object)("[LobbyList] Applied game font to text: " + ((Object)gameFont).name));
			}
			else
			{
				Debug.LogWarning((object)"[LobbyList] No game font available for text, using TMP default");
			}
			((Graphic)val3).color = Color.white;
			((TMP_Text)val3).text = displayText;
			((TMP_Text)val3).fontSize = 24f;
			((TMP_Text)val3).fontStyle = (FontStyles)(useBold ? 1 : 0);
			((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
			val2.sizeDelta = ((TMP_Text)val3).GetPreferredValues();
			return val;
		}

		public static GameObject CreateLobbyItemButton(string lobbyName, Transform parent)
		{
			//IL_0027: 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)
			Color value = default(Color);
			((Color)(ref value))..ctor(0.4f, 0.4f, 0.4f, 0.8f);
			GameObject val = CreateGameStyleButton("LobbyItem_" + lobbyName, parent, value);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(0f, 70f);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredHeight = 70f;
			val2.flexibleWidth = 1f;
			return val;
		}

		public static GameObject CreateLobbyItemButton(string lobbyName, Transform parent, Color customColor)
		{
			//IL_000c: 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)
			GameObject val = CreateGameStyleButton("LobbyItem_" + lobbyName, parent, customColor);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(0f, 70f);
			LayoutElement val2 = val.AddComponent<LayoutElement>();
			val2.preferredHeight = 70f;
			val2.flexibleWidth = 1f;
			return val;
		}

		public static GameObject CreateScrollableArea(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00ad: 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_00d1: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			GameObject val = new GameObject("ScrollArea");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0.1f, 0.15f);
			val2.anchorMax = new Vector2(0.9f, 0.8f);
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			ScrollRect val3 = val.AddComponent<ScrollRect>();
			val3.horizontal = false;
			val3.vertical = true;
			val3.movementType = (MovementType)2;
			val3.scrollSensitivity = 20f;
			GameObject val4 = new GameObject("Viewport");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.offsetMin = Vector2.zero;
			val5.offsetMax = Vector2.zero;
			Mask val6 = val4.AddComponent<Mask>();
			val6.showMaskGraphic = false;
			Image val7 = val4.AddComponent<Image>();
			((Graphic)val7).color = new Color(0.2f, 0.2f, 0.2f, 0.9f);
			GameObject val8 = new GameObject("Content");
			val8.transform.SetParent(val4.transform, false);
			RectTransform val9 = val8.AddComponent<RectTransform>();
			val9.anchorMin = new Vector2(0f, 1f);
			val9.anchorMax = new Vector2(1f, 1f);
			val9.pivot = new Vector2(0.5f, 1f);
			val9.offsetMin = Vector2.zero;
			val9.offsetMax = Vector2.zero;
			VerticalLayoutGroup val10 = val8.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val10).spacing = 10f;
			((LayoutGroup)val10).padding = new RectOffset(20, 20, 20, 20);
			((HorizontalOrVerticalLayoutGroup)val10).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val10).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val10).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val10).childForceExpandWidth = true;
			ContentSizeFitter val11 = val8.AddComponent<ContentSizeFitter>();
			val11.verticalFit = (FitMode)2;
			val3.viewport = val5;
			val3.content = val9;
			Debug.Log((object)"[LobbyList] Created scrollable area");
			return val;
		}

		public static void ExpandToParent(RectTransform rectTransform)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
		}

		public static void SetButtonText(GameObject button, string text)
		{
			TextMeshProUGUI componentInChildren = button.GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)componentInChildren).text = text;
			}
		}

		public static Button? GetButton(GameObject buttonObj)
		{
			return buttonObj.GetComponent<Button>();
		}

		public static TextMeshProUGUI? GetButtonText(GameObject buttonObj)
		{
			return buttonObj.GetComponentInChildren<TextMeshProUGUI>();
		}

		private static GameObject? GetButtonTemplate()
		{
			if ((Object)(object)_buttonTemplate == (Object)null)
			{
				try
				{
					Debug.Log((object)"[LobbyList] Searching for button template in settings menu...");
					MainMenu val = Object.FindFirstObjectByType<MainMenu>();
					if ((Object)(object)val == (Object)null)
					{
						Debug.LogWarning((object)"[LobbyList] MainMenu not found, searching in all MenuWindows");
						MenuWindow[] array = Object.FindObjectsByType<MenuWindow>((FindObjectsSortMode)0);
						MenuWindow[] array2 = array;
						foreach (MenuWindow val2 in array2)
						{
							if (((Object)val2).name.Contains("Settings") || ((Object)val2).name.Contains("Pause"))
							{
								GameObject val3 = FindBackButtonInWindow(val2);
								if ((Object)(object)val3 != (Object)null)
								{
									_buttonTemplate = Object.Instantiate<GameObject>(val3);
									((Object)_buttonTemplate).name = "PeakUIButton_Template";
									Object.DontDestroyOnLoad((Object)(object)_buttonTemplate);
									_buttonTemplate.SetActive(false);
									Debug.Log((object)("[LobbyList] Button template created from " + ((Object)val2).name + " back button"));
									break;
								}
							}
						}
					}
					else
					{
						if ((Object)(object)val.settingsMenu != (Object)null)
						{
							MenuWindow settingsMenu = val.settingsMenu;
							PauseMainMenu val4 = (PauseMainMenu)(object)((settingsMenu is PauseMainMenu) ? settingsMenu : null);
							if (val4 != null)
							{
								if ((Object)(object)val4.backButton != (Object)null)
								{
									_buttonTemplate = Object.Instantiate<GameObject>(((Component)val4.backButton).gameObject);
									((Object)_buttonTemplate).name = "PeakUIButton_Template";
									Object.DontDestroyOnLoad((Object)(object)_buttonTemplate);
									_buttonTemplate.SetActive(false);
									Debug.Log((object)"[LobbyList] Button template created from settingsMenu.backButton");
								}
								else
								{
									Debug.LogWarning((object)"[LobbyList] settingsMenu.backButton is null");
								}
								goto IL_0170;
							}
						}
						Debug.LogWarning((object)"[LobbyList] settingsMenu not found or wrong type");
					}
					goto IL_0170;
					IL_0170:
					if ((Object)(object)_buttonTemplate == (Object)null)
					{
						Debug.LogWarning((object)"[LobbyList] Could not find button template, will use fallback");
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LobbyList] Error getting button template: " + ex.Message));
				}
			}
			return _buttonTemplate;
		}

		private static GameObject? FindBackButtonInWindow(MenuWindow window)
		{
			Button[] componentsInChildren = ((Component)window).GetComponentsInChildren<Button>(true);
			Button[] array = componentsInChildren;
			foreach (Button val in array)
			{
				if (((Object)val).name.ToLower().Contains("back") || ((Object)((Component)val).transform).name.ToLower().Contains("back"))
				{
					Debug.Log((object)("[LobbyList] Found back button: " + ((Object)val).name + " in " + ((Object)window).name));
					return ((Component)val).gameObject;
				}
				TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null && ((TMP_Text)componentInChildren).text.ToLower().Contains("back"))
				{
					Debug.Log((object)("[LobbyList] Found back button by text: " + ((Object)val).name + " in " + ((Object)window).name));
					return ((Component)val).gameObject;
				}
			}
			return null;
		}

		private static void ApplyCustomButtonColor(GameObject buttonObj, Color customColor)
		{
			//IL_0014: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_003c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			Button component = buttonObj.GetComponent<Button>();
			if (!((Object)(object)component != (Object)null))
			{
				return;
			}
			ColorBlock colors = ((Selectable)component).colors;
			((ColorBlock)(ref colors)).normalColor = customColor;
			((ColorBlock)(ref colors)).highlightedColor = Color.Lerp(customColor, Color.white, 0.2f);
			((ColorBlock)(ref colors)).pressedColor = Color.Lerp(customColor, Color.black, 0.2f);
			((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
			((Selectable)component).colors = colors;
			Image[] componentsInChildren = buttonObj.GetComponentsInChildren<Image>();
			Image[] array = componentsInChildren;
			foreach (Image val in array)
			{
				if (((Graphic)val).color.a > 0.01f)
				{
					Color color = customColor;
					color.a = ((Graphic)val).color.a;
					((Graphic)val).color = color;
				}
			}
			Graphic targetGraphic = ((Selectable)component).targetGraphic;
			if ((Object)(object)targetGraphic != (Object)null)
			{
				targetGraphic.color = customColor;
			}
			Debug.Log((object)$"[LobbyList] Applied custom color {customColor} to button {((Object)buttonObj).name}");
		}
	}
	[BepInProcess("PEAK.exe")]
	[BepInPlugin("com.keklick1337.peak.LobbyList", "Peak Lobby List", "0.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <InitializeLobbyList>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitializeLobbyList>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Expected O, but got Unknown
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 2:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 10)
				{
					bool flag = false;
					try
					{
						GameObject val = new GameObject("LobbyListManager");
						Object.DontDestroyOnLoad((Object)(object)val);
						LobbyListUI_Native.Initialize();
						Log.LogInfo((object)"LobbyList initialized successfully!");
						Debug.Log((object)"[LobbyList] Initialized successfully!");
						flag = true;
					}
					catch (Exception ex)
					{
						Log.LogWarning((object)$"Failed to initialize LobbyList (attempt {<i>5__2 + 1}): {ex.Message}");
						Debug.Log((object)$"[LobbyList] Failed to initialize (attempt {<i>5__2 + 1}): {ex.Message}");
					}
					if (flag)
					{
						return false;
					}
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 2;
					return true;
				}
				Log.LogError((object)"Failed to initialize LobbyList after multiple attempts!");
				Debug.Log((object)"[LobbyList] Failed to initialize after multiple attempts!");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ProcessDelayedLobbyJoin>d__14 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ProcessDelayedLobbyJoin>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Log.LogInfo((object)$"Executing delayed lobby join for: {pendingLobbyID}");
					SteamLobbyHandler service = GameHandler.GetService<SteamLobbyHandler>();
					if (service != null)
					{
						service.TryJoinLobby(pendingLobbyID);
						Log.LogInfo((object)"Successfully initiated delayed lobby join!");
					}
					else
					{
						Log.LogError((object)"SteamLobbyHandler not found!");
					}
					hasLobbyJoinRequest = false;
					pendingLobbyID = CSteamID.Nil;
					isProcessingLobbyJoin = false;
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static bool hasLobbyJoinRequest = false;

		private static CSteamID pendingLobbyID = CSteamID.Nil;

		private static bool isProcessingLobbyJoin = false;

		public const string Id = "com.keklick1337.peak.LobbyList";

		internal static ManualLogSource Log { get; private set; } = null;


		internal static Plugin Instance { get; private set; } = null;


		public static string Name => "Peak Lobby List";

		public static string Version => "0.0.1";

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LobbyList Plugin loaded!");
			Debug.Log((object)"[LobbyList] Plugin loaded!");
			try
			{
				Harmony val = new Harmony("com.keklick1337.peak.LobbyList");
				val.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)"Harmony patches applied successfully!");
				Debug.Log((object)"[LobbyList] Harmony patches applied successfully!");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to apply Harmony patches: " + ex.Message));
				Debug.LogError((object)("[LobbyList] Failed to apply Harmony patches: " + ex.Message));
			}
			((MonoBehaviour)this).StartCoroutine(InitializeLobbyList());
		}

		private void Update()
		{
			LobbyListUI_Native.Update();
			if (hasLobbyJoinRequest && !isProcessingLobbyJoin && IsPhotonReady())
			{
				Log.LogInfo((object)"Photon is ready! Processing delayed lobby join...");
				isProcessingLobbyJoin = true;
				((MonoBehaviour)this).StartCoroutine(ProcessDelayedLobbyJoin());
			}
		}

		private bool IsPhotonReady()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (PhotonNetwork.IsConnected && (int)PhotonNetwork.NetworkClientState == 15)
			{
				return PhotonNetwork.AuthValues != null;
			}
			return false;
		}

		[IteratorStateMachine(typeof(<ProcessDelayedLobbyJoin>d__14))]
		private IEnumerator ProcessDelayedLobbyJoin()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ProcessDelayedLobbyJoin>d__14(0);
		}

		public static void DelayLobbyJoin(CSteamID lobbyID)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo((object)$"Delaying lobby join for: {lobbyID}");
			hasLobbyJoinRequest = true;
			pendingLobbyID = lobbyID;
		}

		[IteratorStateMachine(typeof(<InitializeLobbyList>d__16))]
		private IEnumerator InitializeLobbyList()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitializeLobbyList>d__16(0);
		}
	}
	public class SteamLobbyFinder : MonoBehaviour
	{
		public delegate void SteamLobbiesFoundDelegate(List<LobbyInfo> lobbies);

		[CompilerGenerated]
		private sealed class <DelayedSearch>d__20 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SteamLobbyFinder <>4__this;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedSearch>d__20(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				SteamLobbyFinder steamLobbyFinder = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					steamLobbyFinder.PerformLobbySearch();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private bool isSearching;

		private Callback<LobbyMatchList_t>? lobbyMatchListCallback;

		private int currentSearchAttempt;

		private const int MAX_SEARCH_ATTEMPTS = 5;

		private List<LobbyInfo> allFoundLobbies = new List<LobbyInfo>();

		public static event SteamLobbiesFoundDelegate? OnSteamLobbiesFound;

		private void Start()
		{
			if (SteamManager.Initialized)
			{
				lobbyMatchListCallback = Callback<LobbyMatchList_t>.Create((DispatchDelegate<LobbyMatchList_t>)OnLobbyMatchList);
				Debug.Log((object)"[LobbyList] SteamLobbyFinder initialized");
			}
			else
			{
				Debug.LogError((object)"[LobbyList] Steam not initialized - cannot search for Steam lobbies");
			}
		}

		private void OnDestroy()
		{
			lobbyMatchListCallback?.Dispose();
		}

		public void RequestSteamLobbies()
		{
			if (!SteamManager.Initialized)
			{
				Debug.LogError((object)"[LobbyList] Steam not initialized");
				return;
			}
			if (isSearching)
			{
				Debug.Log((object)"[LobbyList] Already searching for Steam lobbies");
				return;
			}
			currentSearchAttempt = 0;
			allFoundLobbies.Clear();
			PerformLobbySearch();
		}

		private void PerformLobbySearch()
		{
			//IL_0098: 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_00a3: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)$"[LobbyList] Requesting Steam lobby list (attempt {currentSearchAttempt + 1}/{5})...");
			isSearching = true;
			switch (currentSearchAttempt)
			{
			case 0:
				SetupBroadSearch();
				break;
			case 1:
				SetupDistanceOnlySearch();
				break;
			case 2:
				SetupVersionSearch();
				break;
			case 3:
				SetupMinimalSearch();
				break;
			case 4:
				SetupNoFiltersSearch();
				break;
			}
			Debug.Log((object)$"[LobbyList] Steam API call details - Attempt: {currentSearchAttempt + 1}, Steam initialized: {SteamManager.Initialized}");
			SteamAPICall_t val = SteamMatchmaking.RequestLobbyList();
			Debug.Log((object)$"[LobbyList] Steam API call result: {val} (Invalid = {SteamAPICall_t.Invalid})");
			if (val == SteamAPICall_t.Invalid)
			{
				Debug.LogError((object)"[LobbyList] Failed to request Steam lobby list");
				isSearching = false;
				TryNextSearch();
			}
			else
			{
				Debug.Log((object)"[LobbyList] Steam lobby search initiated successfully");
			}
		}

		private void SetupBroadSearch()
		{
			Debug.Log((object)"[LobbyList] Using broad search strategy");
			SteamMatchmaking.AddRequestLobbyListDistanceFilter((ELobbyDistanceFilter)3);
			SteamMatchmaking.AddRequestLobbyListResultCountFilter(50);
		}

		private void SetupDistanceOnlySearch()
		{
			Debug.Log((object)"[LobbyList] Using distance-only search strategy");
			SteamMatchmaking.AddRequestLobbyListDistanceFilter((ELobbyDistanceFilter)1);
			SteamMatchmaking.AddRequestLobbyListResultCountFilter(100);
		}

		private void SetupVersionSearch()
		{
			//IL_001c: 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)
			Debug.Log((object)"[LobbyList] Using version-based search strategy");
			SteamMatchmaking.AddRequestLobbyListDistanceFilter((ELobbyDistanceFilter)3);
			SteamMatchmaking.AddRequestLobbyListResultCountFilter(50);
			try
			{
				BuildVersion val = new BuildVersion(Application.version);
				string text = ((BuildVersion)(ref val)).ToMatchmaking();
				SteamMatchmaking.AddRequestLobbyListStringFilter("PeakVersion", text, (ELobbyComparison)0);
				Debug.Log((object)("[LobbyList] Filtering by game version: " + text));
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[LobbyList] Could not set version filter: " + ex.Message));
			}
		}

		private void SetupMinimalSearch()
		{
			Debug.Log((object)"[LobbyList] Using minimal search strategy");
			SteamMatchmaking.AddRequestLobbyListDistanceFilter((ELobbyDistanceFilter)0);
			SteamMatchmaking.AddRequestLobbyListResultCountFilter(100);
		}

		private void SetupNoFiltersSearch()
		{
			Debug.Log((object)"[LobbyList] Using no-filters search strategy");
		}

		private void OnLobbyMatchList(LobbyMatchList_t param)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			//IL_005c: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			isSearching = false;
			Debug.Log((object)$"[LobbyList] Steam returned {param.m_nLobbiesMatching} total lobbies (attempt {currentSearchAttempt + 1})");
			List<LobbyInfo> list = new List<LobbyInfo>();
			for (int i = 0; i < param.m_nLobbiesMatching; i++)
			{
				CSteamID lobbyByIndex = SteamMatchmaking.GetLobbyByIndex(i);
				string text = SteamMatchmaking.GetLobbyData(lobbyByIndex, "name");
				string lobbyData = SteamMatchmaking.GetLobbyData(lobbyByIndex, "CurrentScene");
				string lobbyData2 = SteamMatchmaking.GetLobbyData(lobbyByIndex, "PeakVersion");
				string lobbyData3 = SteamMatchmaking.GetLobbyData(lobbyByIndex, "PhotonRegion");
				Debug.Log((object)$"[LobbyList] Lobby {i}: ID={lobbyByIndex}, Name='{text}', Scene='{lobbyData}', Version='{lobbyData2}', Region='{lobbyData3}'");
				if (string.IsNullOrEmpty(text))
				{
					text = (string.IsNullOrEmpty(lobbyData) ? "PEAK Game" : ("PEAK Game (" + lobbyData + ")"));
				}
				int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(lobbyByIndex);
				int lobbyMemberLimit = SteamMatchmaking.GetLobbyMemberLimit(lobbyByIndex);
				if (!string.IsNullOrEmpty(lobbyData2) || !string.IsNullOrEmpty(lobbyData) || !string.IsNullOrEmpty(lobbyData3))
				{
					LobbyInfo lobbyInfo = new LobbyInfo
					{
						Name = (text ?? ""),
						PlayerCount = numLobbyMembers,
						MaxPlayers = ((lobbyMemberLimit > 0) ? lobbyMemberLimit : 4),
						Region = (lobbyData3 ?? "Unknown"),
						SteamLobbyId = lobbyByIndex,
						IsFromSteam = true
					};
					list.Add(lobbyInfo);
					Debug.Log((object)$"[LobbyList] Added valid PEAK lobby: {lobbyInfo.Name} ({lobbyInfo.PlayerCount}/{lobbyInfo.MaxPlayers})");
				}
				else
				{
					Debug.Log((object)("[LobbyList] Skipped non-PEAK lobby: " + text + " (no game data)"));
				}
			}
			Debug.Log((object)$"[LobbyList] Found {list.Count} valid PEAK lobbies out of {param.m_nLobbiesMatching} total");
			bool flag = false;
			foreach (LobbyInfo newLobby in list)
			{
				if (!allFoundLobbies.Any((LobbyInfo existing) => existing.SteamLobbyId.HasValue && newLobby.SteamLobbyId.HasValue && existing.SteamLobbyId.Value.m_SteamID == newLobby.SteamLobbyId.Value.m_SteamID))
				{
					allFoundLobbies.Add(newLobby);
					flag = true;
					Debug.Log((object)$"[LobbyList] Added new unique lobby: {newLobby.Name} (ID: {newLobby.SteamLobbyId?.m_SteamID})");
				}
				else
				{
					Debug.Log((object)("[LobbyList] Skipped duplicate lobby: " + newLobby.Name));
				}
			}
			Debug.Log((object)$"[LobbyList] Total unique lobbies found so far: {allFoundLobbies.Count}");
			if (flag || currentSearchAttempt == 0)
			{
				Debug.Log((object)$"[LobbyList] Sending {allFoundLobbies.Count} lobbies to UI");
				SteamLobbyFinder.OnSteamLobbiesFound?.Invoke(new List<LobbyInfo>(allFoundLobbies));
			}
			if (currentSearchAttempt < 4)
			{
				Debug.Log((object)$"[LobbyList] Trying next search strategy to find more lobbies (current unique: {allFoundLobbies.Count})...");
				TryNextSearch();
			}
			else
			{
				Debug.Log((object)$"[LobbyList] All search strategies completed. Final result: {allFoundLobbies.Count} unique lobbies");
			}
		}

		private void TryNextSearch()
		{
			currentSearchAttempt++;
			if (currentSearchAttempt < 5)
			{
				Debug.Log((object)$"[LobbyList] Trying search attempt {currentSearchAttempt + 1}...");
				((MonoBehaviour)this).StartCoroutine(DelayedSearch());
			}
			else
			{
				Debug.Log((object)"[LobbyList] All search attempts exhausted");
				SteamLobbyFinder.OnSteamLobbiesFound?.Invoke(new List<LobbyInfo>());
			}
		}

		[IteratorStateMachine(typeof(<DelayedSearch>d__20))]
		private IEnumerator DelayedSearch()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedSearch>d__20(0)
			{
				<>4__this = this
			};
		}
	}
	[HarmonyPatch(typeof(SteamLobbyHandler), "TryJoinLobby", new Type[] { typeof(CSteamID) })]
	public class SteamLobbyHandlerPatch
	{
		private static bool Prefix(CSteamID __0)
		{
			//IL_0021: 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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsConnected || (int)PhotonNetwork.NetworkClientState != 15 || PhotonNetwork.AuthValues == null)
			{
				Plugin.Log.LogInfo((object)$"Photon not ready, delaying lobby join for: {__0}");
				Plugin.DelayLobbyJoin(__0);
				return false;
			}
			Plugin.Log.LogInfo((object)$"Photon ready, allowing immediate lobby join for: {__0}");
			return true;
		}
	}
	[HarmonyPatch(typeof(SteamLobbyHandler), "OnLobbyJoinRequested", new Type[] { typeof(GameLobbyJoinRequested_t) })]
	public class OnLobbyJoinRequestedPatch
	{
		private static bool Prefix(GameLobbyJoinRequested_t param)
		{
			//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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			CSteamID steamIDLobby = param.m_steamIDLobby;
			if (!PhotonNetwork.IsConnected || (int)PhotonNetwork.NetworkClientState != 15 || PhotonNetwork.AuthValues == null)
			{
				Plugin.Log.LogInfo((object)$"Photon not ready, delaying lobby join request for: {steamIDLobby}");
				Plugin.DelayLobbyJoin(steamIDLobby);
				return false;
			}
			Plugin.Log.LogInfo((object)$"Photon ready, allowing immediate lobby j