Decompiled source of LobbyList v0.0.1
BepInEx/plugins/com.keklick1337.peak.LobbyList.dll
Decompiled 5 months ago
The result has been truncated due to the large size, download it to view full contents!
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