The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of LobbyList v0.0.1
BepInEx/plugins/com.keklick1337.peak.LobbyList.dll
Decompiled a month 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