Decompiled source of LobbyImprovements v1.0.7

BepInEx/plugins/LobbyImprovements/uk.1a3.lobbyimprovements.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalModDataLib.Attributes;
using LethalModDataLib.Features;
using LethalModDataLib.Helpers;
using LobbyCompatibility.Behaviours;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using LobbyImprovements.Compatibility;
using LobbyImprovements.LANDiscovery;
using Microsoft.CodeAnalysis;
using MoreCompany;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Steamworks;
using Steamworks.Data;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("BMX.LobbyCompatibility")]
[assembly: AssemblyCompany("uk.1a3.lobbyimprovements")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.7.0")]
[assembly: AssemblyInformationalVersion("1.0.7+0a07dae3f5daff35f4fdc5b737b958fdece3452a")]
[assembly: AssemblyProduct("LobbyImprovements")]
[assembly: AssemblyTitle("uk.1a3.lobbyimprovements")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LobbyImprovements
{
	[HarmonyPatch]
	public class AdditionalSaves
	{
	}
	[HarmonyPatch]
	public class HostingUI
	{
		public static GameObject hostPanel;

		internal static ulong protectedLobbyId;

		internal static string protectedLobbyPassword;

		[HarmonyPatch(typeof(MenuManager), "Awake")]
		[HarmonyPostfix]
		private static void MenuManager_Awake(MenuManager __instance)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ace: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b16: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b3a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b63: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b8c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_079b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0819: Unknown result type (might be due to invalid IL or missing references)
			//IL_083a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0859: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_070b: Expected O, but got Unknown
			//IL_08b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ba: Expected O, but got Unknown
			//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d1: Expected O, but got Unknown
			//IL_096a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a02: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a21: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.isInitScene)
			{
				return;
			}
			Transform val = __instance.HostSettingsScreen.transform.Find("HostSettingsContainer");
			Transform val2 = ((val != null) ? val.Find("LobbyHostOptions") : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			Transform val3 = __instance.HostSettingsScreen.transform.Find("FilesPanel");
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val3.parent);
			((Object)val4).name = "LIPanel_Host";
			hostPanel = val4;
			TextMeshProUGUI component = ((Component)val4.transform.Find("EnterAName")).gameObject.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).transform.localPosition = new Vector3(0f, 100f, 0f);
			((TMP_Text)component).fontSize = 14f;
			((TMP_Text)component).text = "LobbyImprovements";
			val4.transform.localPosition = new Vector3(-252.0869f, -5.648f, -2.785f);
			for (int num = val4.transform.childCount - 1; num >= 0; num--)
			{
				Transform child = val4.transform.GetChild(num);
				if (((Object)child).name != "EnterAName" && ((Object)child).name != "Darken" && ((Object)child).name != "Outline")
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
			Transform obj = val2.Find("OptionsNormal/EnterAName");
			GameObject val5 = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val5 != (Object)null)
			{
				RectTransform component2 = val5.GetComponent<RectTransform>();
				component2.anchorMin = new Vector2(0.5f, 0.5f);
				component2.anchorMax = new Vector2(0.5f, 0.5f);
				component2.pivot = new Vector2(0.5f, 0.5f);
				val5.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
				val5.transform.localPosition = new Vector3(0f, 30f, 0f);
				((TMP_Text)val5.GetComponent<TextMeshProUGUI>()).text = "Server Name:";
				GameObject obj2 = Object.Instantiate<GameObject>(val5.gameObject, val5.transform.parent);
				((Object)obj2).name = "EnterAccess";
				obj2.transform.localPosition = new Vector3(0f, 70f, 0f);
				((TMP_Text)obj2.GetComponent<TextMeshProUGUI>()).text = "Server Access:";
				GameObject obj3 = Object.Instantiate<GameObject>(val5.gameObject, val5.transform.parent);
				((Object)obj3).name = "EnterATag";
				obj3.transform.localPosition = new Vector3(0f, -10f, 0f);
				((TMP_Text)obj3.GetComponent<TextMeshProUGUI>()).text = "Server Tag:";
				GameObject obj4 = Object.Instantiate<GameObject>(val5.gameObject, val4.transform);
				((Object)obj4).name = "EnterAPassword";
				obj4.transform.localPosition = new Vector3(0f, 70f, 0f);
				((TMP_Text)obj4.GetComponent<TextMeshProUGUI>()).fontSize = 12f;
				((TMP_Text)obj4.GetComponent<TextMeshProUGUI>()).text = "Server Password:";
			}
			Transform obj5 = val2.Find("OptionsNormal/ServerTagInputField");
			GameObject val6 = ((obj5 != null) ? ((Component)obj5).gameObject : null);
			if ((Object)(object)val6 != (Object)null)
			{
				RectTransform component3 = val6.GetComponent<RectTransform>();
				component3.sizeDelta = new Vector2(310.55f, 30f);
				component3.anchorMin = new Vector2(0.5f, 0.5f);
				component3.anchorMax = new Vector2(0.5f, 0.5f);
				component3.pivot = new Vector2(0.5f, 0.5f);
				val6.transform.localPosition = new Vector3(0f, -30f, 0f);
				((TMP_Text)((Component)val6.transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>()).fontSize = 16f;
				((TMP_Text)((Component)val6.transform.Find("Text Area/Text")).GetComponent<TextMeshProUGUI>()).fontSize = 16f;
				__instance.lobbyTagInputField = val6.GetComponent<TMP_InputField>();
				if ((Object)(object)val6.transform.parent.Find("ServerNameField") != (Object)null)
				{
					Transform obj6 = val6.transform.parent.Find("ServerNameField");
					Object.Destroy((Object)(object)((obj6 != null) ? ((Component)obj6).gameObject : null));
					GameObject val7 = Object.Instantiate<GameObject>(val6.gameObject, val6.transform.parent);
					((Object)val7).name = "ServerNameField";
					val7.transform.localPosition = new Vector3(0f, 10f, 0f);
					((TMP_Text)((Component)val7.transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>()).text = "Enter a name...";
					__instance.lobbyNameInputField = val7.GetComponent<TMP_InputField>();
				}
				if ((Object)(object)val4.transform.Find("ServerPasswordField") == (Object)null)
				{
					GameObject obj7 = Object.Instantiate<GameObject>(val6.gameObject, val4.transform);
					((Object)obj7).name = "ServerPasswordField";
					obj7.GetComponent<RectTransform>().sizeDelta = new Vector2(200f, 30f);
					obj7.transform.localPosition = new Vector3(0f, 50f, 0f);
					TextMeshProUGUI component4 = ((Component)obj7.transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>();
					((TMP_Text)component4).text = "None";
					((TMP_Text)component4).horizontalAlignment = (HorizontalAlignmentOptions)2;
					((TMP_Text)((Component)obj7.transform.Find("Text Area/Text")).GetComponent<TextMeshProUGUI>()).horizontalAlignment = (HorizontalAlignmentOptions)2;
					obj7.GetComponent<TMP_InputField>().contentType = (ContentType)7;
				}
			}
			GameObject val8 = GameObject.Find("Canvas/MenuContainer/LobbyList/ListPanel/Dropdown");
			if ((Object)(object)val8 != (Object)null && (Object)(object)val2.Find("OptionsNormal/ServerAccessDropdown") == (Object)null)
			{
				GameObject obj8 = Object.Instantiate<GameObject>(val8, val2.Find("OptionsNormal"));
				((Object)obj8).name = "ServerAccessDropdown";
				RectTransform component5 = obj8.GetComponent<RectTransform>();
				component5.sizeDelta = new Vector2(310.55f, 30f);
				component5.anchorMin = new Vector2(0.5f, 0.5f);
				component5.anchorMax = new Vector2(0.5f, 0.5f);
				component5.pivot = new Vector2(0.5f, 0.5f);
				obj8.transform.localScale = new Vector3(0.7172f, 0.7172f, 0.7172f);
				obj8.transform.localPosition = new Vector3(0f, 50f, 0f);
				TMP_Dropdown component6 = obj8.GetComponent<TMP_Dropdown>();
				component6.ClearOptions();
				if (GameNetworkManager.Instance.disableSteam)
				{
					component6.AddOptions(new List<string>(3) { "Public", "IP-only", "Localhost" });
				}
				else
				{
					component6.AddOptions(new List<string>(3) { "Public", "Friends-only", "Invite-only" });
				}
				component6.onValueChanged = new DropdownEvent();
				component6.value = 0;
				((UnityEvent<int>)(object)component6.onValueChanged).AddListener((UnityAction<int>)delegate(int index)
				{
					PluginLoader.setInviteOnly = false;
					if (GameNetworkManager.Instance.disableSteam)
					{
						switch (index)
						{
						case 1:
							PluginLoader.setInviteOnly = true;
							__instance.HostSetLobbyPublic(true);
							break;
						case 2:
							__instance.HostSetLobbyPublic(false);
							break;
						default:
							__instance.HostSetLobbyPublic(true);
							break;
						}
					}
					else
					{
						switch (index)
						{
						case 1:
							__instance.HostSetLobbyPublic(false);
							break;
						case 2:
							PluginLoader.setInviteOnly = true;
							__instance.HostSetLobbyPublic(false);
							break;
						default:
							__instance.HostSetLobbyPublic(true);
							break;
						}
					}
				});
				obj8.SetActive(true);
			}
			GameObject val9 = GameObject.Find("Canvas/MenuContainer/LobbyList/ListPanel/ToggleChallengeSort");
			if ((Object)(object)val9 != (Object)null && (Object)(object)val4.transform.Find("ServerSecureToggle") == (Object)null)
			{
				GameObject val10 = Object.Instantiate<GameObject>(val9, val4.transform);
				((Object)val10).name = "ServerSecureToggle";
				RectTransform component7 = val10.GetComponent<RectTransform>();
				component7.sizeDelta = new Vector2(200f, 30f);
				component7.anchorMin = new Vector2(0.5f, 0.5f);
				component7.anchorMax = new Vector2(0.5f, 0.5f);
				component7.pivot = new Vector2(0.5f, 0.5f);
				val10.transform.localScale = new Vector3(0.7172f, 0.7172f, 0.7172f);
				val10.transform.localPosition = new Vector3(0f, 20f, 0f);
				TextMeshProUGUI componentInChildren = val10.GetComponentInChildren<TextMeshProUGUI>();
				((Component)componentInChildren).GetComponent<RectTransform>().sizeDelta = new Vector2(175f, 30f);
				((TMP_Text)componentInChildren).transform.localPosition = new Vector3(-4f, 0f, 0f);
				((TMP_Text)componentInChildren).fontSize = 12f;
				((TMP_Text)componentInChildren).text = (GameNetworkManager.Instance.disableSteam ? "Validate Clients:" : "Validate Steam Sessions:");
				Image secureToggleIcon = ((Component)val10.transform.Find("Arrow (1)")).GetComponentInChildren<Image>();
				Button componentInChildren2 = val10.GetComponentInChildren<Button>();
				componentInChildren2.onClick = new ButtonClickedEvent();
				((UnityEvent)componentInChildren2.onClick).AddListener((UnityAction)delegate
				{
					if (GameNetworkManager.Instance.disableSteam)
					{
						PluginLoader.lanSecureLobby = !PluginLoader.lanSecureLobby;
						((Behaviour)secureToggleIcon).enabled = PluginLoader.lanSecureLobby;
						SaveLoadHandler.SaveData(ModDataHelper.GetModDataKey((object)typeof(PluginLoader), "lanSecureLobby"));
					}
					else
					{
						PluginLoader.steamSecureLobby = !PluginLoader.steamSecureLobby;
						((Behaviour)secureToggleIcon).enabled = PluginLoader.steamSecureLobby;
						SaveLoadHandler.SaveData(ModDataHelper.GetModDataKey((object)typeof(PluginLoader), "steamSecureLobby"));
					}
				});
				if (GameNetworkManager.Instance.disableSteam)
				{
					((Behaviour)secureToggleIcon).enabled = PluginLoader.lanSecureLobby;
				}
				else
				{
					((Behaviour)secureToggleIcon).enabled = PluginLoader.steamSecureLobby;
				}
				if ((Object)(object)val10.transform.parent.Find("ServerMaxPlayers") == (Object)null)
				{
					GameObject val11 = Object.Instantiate<GameObject>(val10, val10.transform.parent);
					((Object)val11).name = "ServerMaxPlayers";
					((TMP_Text)val11.GetComponentInChildren<TextMeshProUGUI>()).text = "Max Players:";
					val11.transform.localPosition = new Vector3(0f, -85f, 0f);
					Transform obj9 = val11.transform.Find("Arrow");
					Object.Destroy((Object)(object)((obj9 != null) ? ((Component)obj9).gameObject : null));
					Transform obj10 = val11.transform.Find("Arrow (1)");
					Object.Destroy((Object)(object)((obj10 != null) ? ((Component)obj10).gameObject : null));
					if ((Object)(object)val11.transform.Find("MC_CrewCount") == (Object)null)
					{
						GameObject obj11 = Object.Instantiate<GameObject>(val6.gameObject, val11.transform);
						((Object)obj11).name = "MC_CrewCount";
						obj11.GetComponent<RectTransform>().sizeDelta = new Vector2(55f, 30f);
						obj11.transform.localPosition = new Vector3(75f, 0f, 0f);
						((TMP_Text)((Component)obj11.transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>()).text = "4";
						((TMP_Text)((Component)obj11.transform.Find("Text Area/Placeholder")).GetComponent<TextMeshProUGUI>()).horizontalAlignment = (HorizontalAlignmentOptions)2;
						((TMP_Text)((Component)obj11.transform.Find("Text Area/Text")).GetComponent<TextMeshProUGUI>()).horizontalAlignment = (HorizontalAlignmentOptions)2;
						obj11.GetComponent<TMP_InputField>().characterValidation = (CharacterValidation)2;
						obj11.GetComponent<TMP_InputField>().characterLimit = 3;
						obj11.GetComponent<TMP_InputField>().readOnly = !Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany");
					}
				}
			}
			val.Find("Confirm").localScale = new Vector3(0.8f, 0.8f, 0.8f);
			val.Find("Confirm").localPosition = new Vector3(55f, -68f, 0f);
			val.Find("Back").localScale = new Vector3(0.8f, 0.8f, 0.8f);
			val.Find("Back").localPosition = new Vector3(-68f, -68f, 0f);
			((TMP_Text)__instance.privatePublicDescription).transform.localPosition = new Vector3(0f, 110f, 0f);
			((TMP_Text)__instance.tipTextHostSettings).transform.localPosition = new Vector3(0f, -140f, 0f);
			Transform obj12 = __instance.HostSettingsOptionsNormal.transform.Find("Public");
			if (obj12 != null)
			{
				GameObject gameObject = ((Component)obj12).gameObject;
				if (gameObject != null)
				{
					gameObject.SetActive(false);
				}
			}
			Transform obj13 = __instance.HostSettingsOptionsNormal.transform.Find("Private");
			if (obj13 != null)
			{
				GameObject gameObject2 = ((Component)obj13).gameObject;
				if (gameObject2 != null)
				{
					gameObject2.SetActive(false);
				}
			}
		}

		[HarmonyPatch(typeof(MenuManager), "ClickHostButton")]
		[HarmonyPostfix]
		private static void MenuManager_ClickHostButton(MenuManager __instance)
		{
			if (GameNetworkManager.Instance.disableSteam && __instance.HostSettingsOptionsLAN.activeSelf)
			{
				__instance.HostSettingsOptionsLAN.SetActive(false);
				__instance.HostSettingsOptionsNormal.SetActive(true);
				SaveFileUISlot obj = Object.FindFirstObjectByType<SaveFileUISlot>();
				if (obj != null)
				{
					obj.SetButtonColorForAllFileSlots();
				}
				__instance.HostSetLobbyPublic(__instance.hostSettings_LobbyPublic);
			}
			Transform obj2 = __instance.HostSettingsScreen.transform.Find("HostSettingsContainer/LobbyHostOptions/OptionsNormal/ServerAccessDropdown");
			TMP_Dropdown val = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Dropdown>() : null);
			if ((Object)(object)val != (Object)null)
			{
				if (GameNetworkManager.Instance.disableSteam)
				{
					val.value = (PluginLoader.setInviteOnly ? 1 : ((!__instance.hostSettings_LobbyPublic) ? 2 : 0));
				}
				else
				{
					val.value = (PluginLoader.setInviteOnly ? 2 : ((!__instance.hostSettings_LobbyPublic) ? 1 : 0));
				}
			}
		}

		[HarmonyPatch(typeof(MenuManager), "ConfirmHostButton")]
		[HarmonyPrefix]
		private static bool MM_ConfirmHostButton(MenuManager __instance)
		{
			GameObject obj = hostPanel;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = obj.transform.Find("ServerPasswordField");
				if (obj3 == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject = ((Component)obj3).gameObject;
					if (gameObject == null)
					{
						obj2 = null;
					}
					else
					{
						TMP_InputField component = gameObject.GetComponent<TMP_InputField>();
						obj2 = ((component != null) ? component.text : null);
					}
				}
			}
			string text = (string)obj2;
			if (__instance.hostSettings_LobbyPublic && !PluginLoader.setInviteOnly)
			{
				bool flag = string.IsNullOrEmpty(__instance.lobbyTagInputField.text) || __instance.lobbyTagInputField.text == "none";
				if (!string.IsNullOrWhiteSpace(text) && !GameNetworkManager.Instance.disableSteam && flag)
				{
					((TMP_Text)__instance.tipTextHostSettings).text = "Password Protection is not currently usable in 'public' lobbies unless you set a custom lobby tag!";
					return false;
				}
				if (PluginLoader.steamSecureLobby && !GameNetworkManager.Instance.disableSteam && flag)
				{
					((TMP_Text)__instance.tipTextHostSettings).text = "Validate Steam Sessions is not currently usable in 'public' lobbies unless you set a custom lobby tag!";
					return false;
				}
				if (LobbyNameFilter.offensiveWords.Any((string x) => __instance.lobbyNameInputField.text.ToLower().Contains(x)))
				{
					string text2 = "This lobby name is blocked in vanilla. If you wish to use it anyway click confirm again.";
					if (((TMP_Text)__instance.tipTextHostSettings).text != text2)
					{
						((TMP_Text)__instance.tipTextHostSettings).text = text2;
						return false;
					}
				}
			}
			PluginLoader.SetLobbyPassword(text);
			return true;
		}

		[HarmonyPatch(typeof(MenuManager), "DisplayMenuNotification")]
		[HarmonyPostfix]
		private static void MM_DisplayMenuNotification(MenuManager __instance)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Expected O, but got Unknown
			protectedLobbyId = 0uL;
			protectedLobbyPassword = null;
			if (((TMP_Text)__instance.menuNotificationText).text.EndsWith("You have entered an incorrect password."))
			{
				if (!Object.op_Implicit((Object)(object)__instance.menuNotification.transform.Find("Panel/ServerPasswordField")))
				{
					GameObject obj = hostPanel;
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						Transform obj3 = obj.transform.Find("ServerPasswordField");
						obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
					}
					GameObject obj4 = Object.Instantiate<GameObject>((GameObject)obj2, __instance.menuNotification.transform.Find("Panel"));
					((Object)obj4).name = "ServerPasswordField";
					obj4.transform.localPosition = new Vector3(0f, 5f, 0f);
				}
				if (!Object.op_Implicit((Object)(object)__instance.menuNotification.transform.Find("Panel/JoinButton")))
				{
					Transform obj5 = __instance.menuNotification.transform.Find("Panel/ResponseButton");
					GameObject val = ((obj5 != null) ? ((Component)obj5).gameObject : null);
					val.transform.localScale = new Vector3(0.8f, 0.8f, 0.8f);
					val.transform.localPosition = new Vector3(-65f, -65f, 0f);
					GameObject obj6 = Object.Instantiate<GameObject>(val.gameObject, val.transform.parent);
					((Object)obj6).name = "JoinButton";
					obj6.transform.localPosition = new Vector3(65f, -65f, 0f);
					((TMP_Text)obj6.GetComponentInChildren<TextMeshProUGUI>()).text = "[ Join ]";
					((UnityEvent)obj6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
					{
						Transform obj11 = __instance.menuNotification.transform.Find("Panel/ServerPasswordField");
						object obj12;
						if (obj11 == null)
						{
							obj12 = null;
						}
						else
						{
							TMP_InputField component = ((Component)obj11).GetComponent<TMP_InputField>();
							obj12 = ((component != null) ? component.text : null);
						}
						protectedLobbyPassword = (string)obj12;
						if (GameNetworkManager.Instance.disableSteam)
						{
							__instance.StartAClient();
						}
						else
						{
							SteamLobbyManager _instance = Object.FindFirstObjectByType<SteamLobbyManager>();
							((MonoBehaviour)__instance).StartCoroutine(LobbyCodes_Steam.JoinLobbyByID(_instance, protectedLobbyId));
						}
					});
				}
				if (!GameNetworkManager.Instance.disableSteam && GameNetworkManager.Instance.currentLobby.HasValue)
				{
					Lobby value = GameNetworkManager.Instance.currentLobby.Value;
					protectedLobbyId = SteamId.op_Implicit(((Lobby)(ref value)).Id);
				}
				bool active = protectedLobbyId != 0L || GameNetworkManager.Instance.disableSteam;
				Transform obj7 = __instance.menuNotification.transform.Find("Panel/ServerPasswordField");
				if (obj7 != null)
				{
					GameObject gameObject = ((Component)obj7).gameObject;
					if (gameObject != null)
					{
						gameObject.SetActive(active);
					}
				}
				Transform obj8 = __instance.menuNotification.transform.Find("Panel/JoinButton");
				if (obj8 != null)
				{
					GameObject gameObject2 = ((Component)obj8).gameObject;
					if (gameObject2 != null)
					{
						gameObject2.SetActive(active);
					}
				}
				return;
			}
			Transform obj9 = __instance.menuNotification.transform.Find("Panel/ServerPasswordField");
			if (obj9 != null)
			{
				GameObject gameObject3 = ((Component)obj9).gameObject;
				if (gameObject3 != null)
				{
					gameObject3.SetActive(false);
				}
			}
			Transform obj10 = __instance.menuNotification.transform.Find("Panel/JoinButton");
			if (obj10 != null)
			{
				GameObject gameObject4 = ((Component)obj10).gameObject;
				if (gameObject4 != null)
				{
					gameObject4.SetActive(false);
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated")]
		[HarmonyPostfix]
		private static void SteamMatchmaking_OnLobbyCreated(ref GameNetworkManager __instance, ref Result result, ref Lobby lobby)
		{
			if (PluginLoader.setInviteOnly)
			{
				__instance.lobbyHostSettings.isLobbyPublic = false;
				((Lobby)(ref lobby)).SetPrivate();
			}
			if (!string.IsNullOrWhiteSpace(PluginLoader.lobbyPassword))
			{
				((Lobby)(ref lobby)).SetData("password", "1");
			}
			if (PluginLoader.steamSecureLobby)
			{
				((Lobby)(ref lobby)).SetData("li_secure", "1");
			}
		}

		[HarmonyPatch(typeof(QuickMenuManager), "NonHostPlayerSlotsEnabled")]
		[HarmonyPostfix]
		private static void NonHostPlayerSlotsEnabled(ref bool __result)
		{
			__result = true;
		}
	}
	public class LobbyCodes
	{
		internal static void AddButtonToCopyLobbyCode(Button LobbyJoinBtn, string lobbyCodeStr, string[] textLabels)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			if ((Object)(object)LobbyJoinBtn != (Object)null)
			{
				Button val = Object.Instantiate<Button>(LobbyJoinBtn, ((Component)LobbyJoinBtn).transform.parent);
				((Object)val).name = "CopyCodeButton";
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				component.anchoredPosition -= new Vector2(78f, 0f);
				TextMeshProUGUI LobbyCodeTextMesh = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
				((TMP_Text)LobbyCodeTextMesh).text = textLabels[0];
				val.onClick = new ButtonClickedEvent();
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					CopyLobbyCodeToClipboard(lobbyCodeStr, LobbyCodeTextMesh, textLabels);
				});
			}
		}

		internal static void CopyLobbyCodeToClipboard(string lobbyCode, TextMeshProUGUI textMesh, string[] textLabels)
		{
			if (!(((TMP_Text)textMesh).text != textLabels[0]))
			{
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(LobbySlotCopyCode(lobbyCode, textMesh, textLabels));
			}
		}

		internal static IEnumerator LobbySlotCopyCode(string lobbyCode, TextMeshProUGUI textMesh, string[] textLabels)
		{
			if (!Utility.IsNullOrWhiteSpace(lobbyCode))
			{
				GUIUtility.systemCopyBuffer = lobbyCode;
				PluginLoader.StaticLogger.LogInfo((object)("Lobby code copied to clipboard: " + lobbyCode));
				((TMP_Text)textMesh).text = textLabels[1];
			}
			else
			{
				((TMP_Text)textMesh).text = textLabels[2];
			}
			yield return (object)new WaitForSeconds(1.2f);
			((TMP_Text)textMesh).text = textLabels[0];
		}
	}
	public class LobbyCodes_Steam
	{
		internal static IEnumerator JoinLobbyByID(SteamLobbyManager __instance, ulong lobbyId)
		{
			if (!GameNetworkManager.Instance.waitingForLobbyDataRefresh)
			{
				Lobby val = default(Lobby);
				((Lobby)(ref val))..ctor(SteamId.op_Implicit(lobbyId));
				ManualLogSource staticLogger = PluginLoader.StaticLogger;
				SteamId id = ((Lobby)(ref val)).Id;
				staticLogger.LogWarning((object)("Attempting to join lobby by id: " + ((object)(SteamId)(ref id)).ToString()));
				LobbySlot.JoinLobbyAfterVerifying(val, ((Lobby)(ref val)).Id);
				__instance.serverTagInputField.text = "";
			}
			yield break;
		}
	}
	public class LobbyCodes_LAN
	{
		internal static string GetGlobalIPAddress(bool IPv6 = false, bool external = false)
		{
			if (!external && !IPv6)
			{
				NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
				foreach (NetworkInterface networkInterface in allNetworkInterfaces)
				{
					if (networkInterface.OperationalStatus != OperationalStatus.Up || networkInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback)
					{
						continue;
					}
					foreach (UnicastIPAddressInformation unicastAddress in networkInterface.GetIPProperties().UnicastAddresses)
					{
						if (unicastAddress.Address.AddressFamily == (AddressFamily)(IPv6 ? 23 : 2) && !IPAddress.IsLoopback(unicastAddress.Address))
						{
							return unicastAddress.Address.ToString();
						}
					}
				}
				if (!IPv6)
				{
					return "127.0.0.1";
				}
				return "::1";
			}
			string result = "0.0.0.0";
			string requestUriString = (IPv6 ? "https://api6.ipify.org/" : "https://api.ipify.org/");
			try
			{
				WebRequest webRequest = WebRequest.Create(requestUriString);
				webRequest.Timeout = 2000;
				using StreamReader streamReader = new StreamReader(((HttpWebResponse)webRequest.GetResponse()).GetResponseStream());
				result = streamReader.ReadToEnd();
				streamReader.Close();
			}
			catch (Exception ex)
			{
				PluginLoader.StaticLogger.LogError((object)ex);
			}
			return result;
		}

		internal static bool TryParseIpAndPort(string input, out IPAddress ipAddress, out int port)
		{
			ipAddress = null;
			port = 0;
			int num = input.IndexOf('%');
			if (num != -1)
			{
				input = input.Substring(0, num);
			}
			if (input.StartsWith("[") && input.Contains("]"))
			{
				int num2 = input.IndexOf(']');
				if (num2 == -1)
				{
					return false;
				}
				string ipString = input.Substring(1, num2 - 1);
				string text = input.Substring(num2 + 1);
				if (text.StartsWith(":"))
				{
					text = text.Substring(1);
					if (!int.TryParse(text, out port) || port < 0 || port > 65535)
					{
						return false;
					}
				}
				return IPAddress.TryParse(ipString, out ipAddress);
			}
			int num3 = input.LastIndexOf(':');
			if (num3 == -1)
			{
				return IPAddress.TryParse(input, out ipAddress);
			}
			string ipString2 = input.Substring(0, num3);
			if (!int.TryParse(input.Substring(num3 + 1), out port) || port < 0 || port > 65535)
			{
				return false;
			}
			return IPAddress.TryParse(ipString2, out ipAddress);
		}

		internal static void JoinLobbyByIP(string IP_Address, ushort Port = 0, LANLobby lanLobby = null)
		{
			if (!LANLobbyManager_InGame.waitingForLobbyDataRefresh)
			{
				if (Port == 0)
				{
					Port = (ushort)PluginLoader.lanDefaultPort.Value;
				}
				((Component)NetworkManager.Singleton).GetComponent<UnityTransport>().ConnectionData.Address = IP_Address;
				((Component)NetworkManager.Singleton).GetComponent<UnityTransport>().ConnectionData.Port = Port;
				PluginLoader.StaticLogger.LogInfo((object)$"Listening to LAN server: {IP_Address}:{Port}");
				LANLobbyManager_InGame.UpdateCurrentLANLobby(lanLobby, reset: false, startAClient: true);
			}
		}
	}
	[HarmonyPatch]
	public class LobbyNameFilter
	{
		public static string[] offensiveWords = new string[26]
		{
			"nigger", "faggot", "n1g", "nigers", "cunt", "pussies", "pussy", "minors", "children", "kids",
			"chink", "buttrape", "molest", "rape", "coon", "negro", "beastiality", "cocks", "cumshot", "ejaculate",
			"pedophile", "furfag", "necrophilia", "yiff", "sex", "porn"
		};

		[HarmonyPatch(typeof(SteamLobbyManager), "OnEnable")]
		[HarmonyPrefix]
		private static void Prefix(ref SteamLobbyManager __instance)
		{
			__instance.censorOffensiveLobbyNames = PluginLoader.lobbyNameFilterEnabled.Value && PluginLoader.lobbyNameParsedBlacklist.Length != 0;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspileMoveNext(IEnumerable<CodeInstruction> instructions)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			bool flag = false;
			bool flag2 = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (!flag2)
				{
					if (!flag && instruction.opcode == OpCodes.Ldc_I4_S)
					{
						list.Add(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(PluginLoader), "lobbyNameParsedBlacklist")));
						flag = true;
					}
					else if (flag && instruction.opcode == OpCodes.Stfld)
					{
						flag = false;
						flag2 = true;
					}
					if (flag)
					{
						continue;
					}
				}
				list.Add(instruction);
			}
			if (!flag2)
			{
				PluginLoader.StaticLogger.LogWarning((object)"LobbyNameFilter failed to replace offensiveWords");
			}
			IEnumerable<CodeInstruction> source;
			if (!flag2)
			{
				source = instructions;
			}
			else
			{
				IEnumerable<CodeInstruction> enumerable = list;
				source = enumerable;
			}
			return source.AsEnumerable();
		}
	}
	public enum LIBeginAuthResult
	{
		None = -1,
		OK,
		InvalidTicket,
		DuplicateRequest,
		InvalidVersion,
		GameMismatch,
		ExpiredTicket
	}
	public enum LIAuthResponse
	{
		None = -1,
		OK,
		UserNotConnectedToSteam,
		NoLicenseOrExpired,
		VACBanned,
		LoggedInElseWhere,
		VACCheckTimedOut,
		AuthTicketCanceled,
		AuthTicketInvalidAlreadyUsed,
		AuthTicketInvalid,
		PublisherIssuedBan
	}
	public enum LIMinimalAuthResult
	{
		None = -1,
		OK,
		Invalid
	}
	[Serializable]
	public class SV_SteamPlayer
	{
		public ulong actualClientId;

		public SteamId steamId;

		public LIBeginAuthResult authResult1 = LIBeginAuthResult.None;

		public LIAuthResponse authResult2 = LIAuthResponse.None;
	}
	[Serializable]
	public class CL_SteamPlayer
	{
		public ulong actualClientId;

		public LIMinimalAuthResult authResult1 = LIMinimalAuthResult.None;

		public LIMinimalAuthResult authResult2 = LIMinimalAuthResult.None;
	}
	[Serializable]
	public class SV_LANPlayer
	{
		public ulong actualClientId;

		public string playerName = "PlayerName";

		public string hwidToken;

		public bool banned;

		public string banReason;
	}
	[Serializable]
	public class CL_LANPlayer
	{
		public ulong actualClientId;

		public string playerName = "PlayerName";
	}
	[HarmonyPatch]
	public static class PlayerManager
	{
		internal static List<SV_SteamPlayer> sv_steamPlayers = new List<SV_SteamPlayer>();

		internal static List<CL_SteamPlayer> cl_steamPlayers = new List<CL_SteamPlayer>();

		internal static List<SV_LANPlayer> sv_lanPlayers = new List<SV_LANPlayer>();

		internal static List<CL_LANPlayer> cl_lanPlayers = new List<CL_LANPlayer>();
	}
	[BepInPlugin("uk.1a3.lobbyimprovements", "LobbyImprovements", "1.0.7")]
	internal class PluginLoader : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("uk.1a3.lobbyimprovements");

		private static bool initialized;

		public static ConfigEntry<bool> recentlyPlayedWithOrbit;

		public static ConfigEntry<bool> lobbyNameFilterEnabled;

		public static ConfigEntry<bool> lobbyNameFilterDefaults;

		public static ConfigEntry<string> lobbyNameFilterWhitelist;

		public static ConfigEntry<string> lobbyNameFilterBlacklist;

		public static string[] lobbyNameParsedBlacklist;

		public static ConfigEntry<int> lanDefaultPort;

		public static ConfigEntry<int> lanDiscoveryPort;

		public static ConfigEntry<bool> lanIPv6Enabled;

		public static string lobbyPassword = null;

		public static bool setInviteOnly = false;

		public static PluginLoader Instance { get; private set; }

		internal static ManualLogSource StaticLogger { get; private set; }

		internal static ConfigFile StaticConfig { get; private set; }

		[ModData(/*Could not decode attribute arguments.*/)]
		public static string lanPlayerName { get; set; } = "PlayerName";


		[ModData(/*Could not decode attribute arguments.*/)]
		public static bool steamSecureLobby { get; set; } = false;


		[ModData(/*Could not decode attribute arguments.*/)]
		public static bool lanSecureLobby { get; set; } = false;


		public static void SetLobbyPassword(string password)
		{
			//IL_0083: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			lobbyPassword = (string.IsNullOrWhiteSpace(password) ? null : password);
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && !GameNetworkManager.Instance.disableSteam && GameNetworkManager.Instance.isHostingGame && GameNetworkManager.Instance.currentLobby.HasValue)
			{
				Lobby value;
				if (lobbyPassword != null)
				{
					value = GameNetworkManager.Instance.currentLobby.Value;
					((Lobby)(ref value)).SetData("password", "1");
				}
				else
				{
					value = GameNetworkManager.Instance.currentLobby.Value;
					((Lobby)(ref value)).DeleteData("password");
				}
			}
		}

		public static int GetMaxPlayers()
		{
			if ((StartOfRound.Instance?.allPlayerScripts?.Length).GetValueOrDefault(4) > 4)
			{
				return StartOfRound.Instance.allPlayerScripts.Length;
			}
			if (Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				try
				{
					return MoreCompany_Compat.GetMaxPlayers();
				}
				catch
				{
				}
			}
			return 4;
		}

		private void Awake()
		{
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			if (initialized)
			{
				return;
			}
			initialized = true;
			Instance = this;
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			StaticConfig = ((BaseUnityPlugin)this).Config;
			recentlyPlayedWithOrbit = StaticConfig.Bind<bool>("Steam", "Recent Players In Orbit", true, "Should players be added to the steam recent players list whilst you are in orbit? Disabling this will only add players once the ship has landed.");
			lobbyNameFilterEnabled = StaticConfig.Bind<bool>("Lobby Names", "Filter Enabled", true, "Should the lobby name filter be enabled?");
			lobbyNameFilterEnabled.SettingChanged += delegate
			{
				if ((Object)(object)Object.FindFirstObjectByType<SteamLobbyManager>() != (Object)null)
				{
					UpdateLobbyNameFilter();
				}
			};
			lobbyNameFilterDefaults = StaticConfig.Bind<bool>("Lobby Names", "Default Words", true, "Should Zeekerss' blocked words be filtered? Words: " + string.Join(',', LobbyNameFilter.offensiveWords));
			lobbyNameFilterDefaults.SettingChanged += delegate
			{
				UpdateLobbyNameFilter();
			};
			lobbyNameFilterWhitelist = StaticConfig.Bind<string>("Lobby Names", "Whitelisted Terms", "", "This should be a comma-separated list.");
			lobbyNameFilterWhitelist.SettingChanged += delegate
			{
				UpdateLobbyNameFilter();
			};
			lobbyNameFilterBlacklist = StaticConfig.Bind<string>("Lobby Names", "Blacklisted Terms", "", "This should be a comma-separated list.");
			lobbyNameFilterBlacklist.SettingChanged += delegate
			{
				UpdateLobbyNameFilter();
			};
			UpdateLobbyNameFilter();
			AcceptableValueRange<int> val = new AcceptableValueRange<int>(1, 65535);
			lanDefaultPort = StaticConfig.Bind<int>("LAN", "Default Port", 7777, new ConfigDescription("The port used for hosting a server", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			lanDiscoveryPort = StaticConfig.Bind<int>("LAN", "Discovery Port", 47777, new ConfigDescription("The port used for lobby discovery", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			lanIPv6Enabled = StaticConfig.Bind<bool>("LAN", "IPv6", false, "Should the server listen for IPv6 connections instead of IPv4?");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			harmony.PatchAll(executingAssembly);
			StaticLogger.LogInfo((object)"Patches Loaded");
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				LobbyCompatibility_Compat.Init(harmony);
			}
		}

		private static void UpdateLobbyNameFilter()
		{
			string[] parsedWhitelist = (from x in lobbyNameFilterWhitelist.Value.Split(',')
				select x.Trim() into x
				where x.Length > 0
				select x).ToArray();
			string[] second = (from x in lobbyNameFilterBlacklist.Value.Split(',')
				select x.Trim() into x
				where x.Length > 0
				select x).ToArray();
			lobbyNameParsedBlacklist = (from x in LobbyNameFilter.offensiveWords.Union(second)
				where !parsedWhitelist.Contains(x)
				select x.ToLower()).ToArray();
			SteamLobbyManager val = Object.FindFirstObjectByType<SteamLobbyManager>();
			if ((Object)(object)val != (Object)null)
			{
				val.censorOffensiveLobbyNames = lobbyNameFilterEnabled.Value && lobbyNameParsedBlacklist.Length != 0;
			}
		}
	}
	[HarmonyPatch]
	internal class General_Patches
	{
		public static string kickReason = null;

		public const string kickPrefixStr = "<size=12><color=red>Kicked From Lobby:<color=white>\n";

		public const string banPrefixStr = "<size=12><color=red>Banned From Lobby:<color=white>\n";

		public static Dictionary<ulong, string> steamBanReasons = new Dictionary<ulong, string>();

		[HarmonyPatch(typeof(SteamLobbyManager), "OnEnable")]
		[HarmonyPostfix]
		private static void SLM_OnEnable(SteamLobbyManager __instance)
		{
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance))
			{
				GameNetworkManager.Instance.waitingForLobbyDataRefresh = false;
				if (GameNetworkManager.Instance.disableSteam)
				{
					((TMP_Text)((Component)__instance.serverTagInputField.placeholder).gameObject.GetComponent<TextMeshProUGUI>()).text = "Enter tag or ip...";
					if (__instance.serverTagInputField.characterLimit < 55)
					{
						__instance.serverTagInputField.characterLimit = 55;
					}
				}
				else
				{
					((TMP_Text)((Component)__instance.serverTagInputField.placeholder).gameObject.GetComponent<TextMeshProUGUI>()).text = "Enter tag or id...";
				}
			}
			if (Object.op_Implicit((Object)(object)__instance.levelListContainer) && !Object.op_Implicit((Object)(object)((Component)__instance.levelListContainer).gameObject.GetComponentInChildren<ContentSizeFitter>()))
			{
				ContentSizeFitter obj = ((Component)__instance.levelListContainer).gameObject.AddComponent<ContentSizeFitter>();
				obj.verticalFit = (FitMode)2;
				obj.horizontalFit = (FitMode)0;
				VerticalLayoutGroup obj2 = ((Component)__instance.levelListContainer).gameObject.AddComponent<VerticalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f;
				((LayoutGroup)obj2).childAlignment = (TextAnchor)0;
				((HorizontalOrVerticalLayoutGroup)obj2).reverseArrangement = false;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			}
		}

		[HarmonyPatch(typeof(SteamLobbyManager), "RefreshServerListButton")]
		[HarmonyPrefix]
		private static bool SteamLobbyManager_RefreshServerListButton(SteamLobbyManager __instance)
		{
			if (__instance.serverTagInputField.text != string.Empty)
			{
				ulong result;
				if (GameNetworkManager.Instance.disableSteam)
				{
					if (LobbyCodes_LAN.TryParseIpAndPort(__instance.serverTagInputField.text, out var ipAddress, out var port))
					{
						LobbyCodes_LAN.JoinLobbyByIP(ipAddress.ToString(), (ushort)port);
						return false;
					}
				}
				else if (ulong.TryParse(__instance.serverTagInputField.text, out result) && result.ToString().Length >= 15 && result.ToString().Length <= 20)
				{
					((MonoBehaviour)__instance).StartCoroutine(LobbyCodes_Steam.JoinLobbyByID(__instance, result));
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(SteamLobbyManager), "loadLobbyListAndFilter")]
		[HarmonyPrefix]
		private static void loadLobbyListAndFilter_Prefix(ref Lobby[] lobbyList)
		{
			Array.Sort(lobbyList, (Lobby x, Lobby y) => (((Lobby)(ref x)).MemberCount == ((Lobby)(ref y)).MemberCount) ? ((((Lobby)(ref x)).MaxMembers == ((Lobby)(ref y)).MaxMembers) ? ((Lobby)(ref x)).GetData("name").CompareTo(((Lobby)(ref y)).GetData("name")) : (((Lobby)(ref y)).MaxMembers - ((Lobby)(ref x)).MaxMembers)) : (((Lobby)(ref y)).MemberCount - ((Lobby)(ref x)).MemberCount));
		}

		[HarmonyPatch(typeof(SteamLobbyManager), "loadLobbyListAndFilter")]
		[HarmonyPostfix]
		private static IEnumerator loadLobbyListAndFilter(IEnumerator result)
		{
			SteamLobbyManager val = Object.FindFirstObjectByType<SteamLobbyManager>();
			if (val != null)
			{
				TextMeshProUGUI serverListBlankText = val.serverListBlankText;
				if (serverListBlankText != null)
				{
					GameObject gameObject = ((Component)serverListBlankText).gameObject;
					if (gameObject != null)
					{
						gameObject.SetActive(false);
					}
				}
			}
			while (result.MoveNext())
			{
				yield return result.Current;
			}
			val = Object.FindFirstObjectByType<SteamLobbyManager>();
			if (val != null)
			{
				TextMeshProUGUI serverListBlankText2 = val.serverListBlankText;
				if (serverListBlankText2 != null)
				{
					GameObject gameObject2 = ((Component)serverListBlankText2).gameObject;
					if (gameObject2 != null)
					{
						gameObject2.SetActive(((TMP_Text)val.serverListBlankText).text != string.Empty);
					}
				}
			}
			GameNetworkManager.Instance.waitingForLobbyDataRefresh = false;
			LobbySlot[] array = Object.FindObjectsByType<LobbySlot>((FindObjectsSortMode)1);
			foreach (LobbySlot val2 in array)
			{
				((TMP_Text)val2.playerCount).text = $"{((Lobby)(ref val2.thisLobby)).MemberCount} / {((Lobby)(ref val2.thisLobby)).MaxMembers}";
				Transform obj = ((Component)val2).transform.Find("JoinButton");
				Button val3 = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null);
				if (Object.op_Implicit((Object)(object)val3) && !Object.op_Implicit((Object)(object)((Component)val2).transform.Find("CopyCodeButton")))
				{
					((Component)val3).transform.localPosition = new Vector3(405f, -8.5f, -4.1f);
					((Component)val3).transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);
				}
				List<string> list = new List<string>();
				if (((Lobby)(ref val2.thisLobby)).GetData("chal") == "t")
				{
					Transform obj2 = ((Component)val2).transform.Find("NumPlayers (1)");
					TextMeshProUGUI obj3 = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null);
					if (obj3 != null)
					{
						GameObject gameObject3 = ((Component)obj3).gameObject;
						if (gameObject3 != null)
						{
							gameObject3.SetActive(false);
						}
					}
					list.Add("<color=purple>CHALLENGE</color>");
				}
				if (((Lobby)(ref val2.thisLobby)).GetData("password") == "1")
				{
					list.Add("<color=yellow>PASSWORD</color>");
				}
				if (((Lobby)(ref val2.thisLobby)).GetData("li_secure") == "1")
				{
					list.Add("<color=green>SECURE</color>");
				}
				GameObject obj4 = Object.Instantiate<GameObject>(((Component)val2.playerCount).gameObject, ((Component)val2).transform);
				((Object)obj4).name = "TagsText";
				TextMeshProUGUI val4 = ((obj4 != null) ? obj4.GetComponent<TextMeshProUGUI>() : null);
				if ((Object)(object)val4 != (Object)null)
				{
					((TMP_Text)val4).transform.localPosition = new Vector3(-25f, -15f, 0f);
					((TMP_Text)val4).transform.localScale = new Vector3(1f, 1f, 1f);
					((TMP_Text)val4).horizontalAlignment = (HorizontalAlignmentOptions)4;
					((TMP_Text)val4).alpha = 0.4f;
					((TMP_Text)val4).text = string.Join(", ", list);
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "KickPlayer")]
		[HarmonyTranspiler]
		[HarmonyPriority(800)]
		private static IEnumerable<CodeInstruction> StartOfRound_KickPlayer(IEnumerable<CodeInstruction> instructions)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			bool flag = false;
			bool flag2 = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (!flag2)
				{
					if (!flag && instruction.opcode == OpCodes.Ldfld && instruction.operand?.ToString() == "System.UInt64 actualClientId")
					{
						flag = true;
						list.Add(instruction);
						CodeInstruction item = new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(General_Patches), "kickReason"));
						list.Add(item);
						continue;
					}
					if (flag && instruction.opcode == OpCodes.Callvirt && instruction.operand?.ToString() == "Void DisconnectClient(UInt64)")
					{
						flag2 = true;
						instruction.operand = AccessTools.Method(typeof(NetworkManager), "DisconnectClient", new Type[2]
						{
							typeof(ulong),
							typeof(string)
						}, (Type[])null);
					}
				}
				list.Add(instruction);
			}
			if (!flag2)
			{
				PluginLoader.StaticLogger.LogWarning((object)"KickPlayer failed to add reason");
			}
			IEnumerable<CodeInstruction> source;
			if (!flag2)
			{
				source = instructions;
			}
			else
			{
				IEnumerable<CodeInstruction> enumerable = list;
				source = enumerable;
			}
			return source.AsEnumerable();
		}

		[HarmonyPatch(typeof(MenuManager), "EnableLeaderboardDisplay")]
		[HarmonyPostfix]
		private static void MM_EnableLeaderboardDisplay(MenuManager __instance, bool enable)
		{
			if (!enable)
			{
				__instance.HostSetLobbyPublic(__instance.hostSettings_LobbyPublic);
			}
		}

		private static string parseConnectionData(string[] array)
		{
			return string.Join(',', array.Select((string x) => (!x.StartsWith("ticket:")) ? ((!x.StartsWith("hwid:")) ? ((!x.StartsWith("password:")) ? x : $"password:{x.Substring(9).Length}") : $"hwid:{x.Substring(5).Length}") : $"ticket:{x.Substring(7).Length}"));
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SetConnectionDataBeforeConnecting")]
		[HarmonyPostfix]
		private static void SetConnectionDataBeforeConnecting(GameNetworkManager __instance)
		{
			string @string = Encoding.ASCII.GetString(NetworkManager.Singleton.NetworkConfig.ConnectionData);
			List<string> list = new List<string>(1) { @string };
			if (!string.IsNullOrWhiteSpace(HostingUI.protectedLobbyPassword))
			{
				list.Add("password:" + HostingUI.protectedLobbyPassword);
				HostingUI.protectedLobbyPassword = null;
			}
			else
			{
				list.Add("password:");
			}
			if (__instance.disableSteam)
			{
				list.Add("playername:" + PluginLoader.lanPlayerName.Replace(',', '.'));
				list.Add("hwid:" + SystemInfo.deviceUniqueIdentifier);
			}
			else
			{
				SessionTickets_Client.currentTicket = SteamUser.GetAuthSessionTicket();
				list.Add("ticket:" + string.Join(';', SessionTickets_Client.currentTicket.Data));
			}
			PluginLoader.StaticLogger.LogInfo((object)("SetConnectionDataBeforeConnecting: " + parseConnectionData(list.ToArray())));
			NetworkManager.Singleton.NetworkConfig.ConnectionData = Encoding.ASCII.GetBytes(string.Join(',', list));
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ConnectionApproval_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>();
			bool flag = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (!flag && instruction.opcode == OpCodes.Ldstr && instruction.operand?.ToString() == "Joining client id: {0}; Local/host client id: {1}")
				{
					flag = true;
				}
				if (flag)
				{
					list.Add(instruction);
				}
			}
			if (!flag)
			{
				PluginLoader.StaticLogger.LogWarning((object)"ConnectionApproval failed to replace log");
			}
			if (!flag)
			{
				return instructions;
			}
			return list.AsEnumerable();
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		[HarmonyPrefix]
		private static void ConnectionApproval_Prefix(ref ConnectionApprovalRequest request, ref ConnectionApprovalResponse response)
		{
			string[] array = Encoding.ASCII.GetString(request.Payload).Split(",");
			Debug.Log((object)("Connection approval callback! Game version of client request: " + parseConnectionData(array)));
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
		[HarmonyPostfix]
		private static void ConnectionApproval_Postfix(GameNetworkManager __instance, ref ConnectionApprovalRequest request, ref ConnectionApprovalResponse response)
		{
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Expected I4, but got Unknown
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			if (request.ClientNetworkId == NetworkManager.Singleton.LocalClientId)
			{
				return;
			}
			string[] array = Encoding.ASCII.GetString(request.Payload).Split(",");
			string text = "You cannot rejoin after being kicked.";
			if (!response.Approved && response.Reason == text)
			{
				ulong key = (ulong)Convert.ToInt64(array[1]);
				if (steamBanReasons.ContainsKey(key))
				{
					response.Reason = steamBanReasons[key];
				}
				return;
			}
			SV_LANPlayer lanPlayer = new SV_LANPlayer
			{
				actualClientId = request.ClientNetworkId
			};
			if (response.Approved && __instance.disableSteam)
			{
				if (array.Any((string x) => x.StartsWith("hwid:")))
				{
					lanPlayer.hwidToken = array.First((string x) => x.StartsWith("hwid:")).Substring(5);
					if (PlayerManager.sv_lanPlayers.Any((SV_LANPlayer x) => x.hwidToken == lanPlayer.hwidToken && x.banned))
					{
						SV_LANPlayer sV_LANPlayer = PlayerManager.sv_lanPlayers.FindLast((SV_LANPlayer x) => x.hwidToken == lanPlayer.hwidToken && x.banned);
						if (!string.IsNullOrWhiteSpace(sV_LANPlayer.banReason))
						{
							response.Reason = sV_LANPlayer.banReason;
						}
						else
						{
							response.Reason = text;
						}
						response.Approved = false;
					}
				}
				else if (PluginLoader.lanSecureLobby)
				{
					string text2 = "<size=12><color=red>LobbyImprovements:<color=white>\n";
					response.Reason = text2 + "This lobby requires you to have the LobbyImprovements mod.";
					response.Approved = false;
				}
			}
			if (response.Approved && !string.IsNullOrWhiteSpace(PluginLoader.lobbyPassword))
			{
				string text3 = "<size=12><color=red>Password Protection:<color=white>\n";
				if (array.Any((string x) => x.StartsWith("password:")))
				{
					string text4 = array.First((string x) => x.StartsWith("password:")).Substring(9);
					if (PluginLoader.lobbyPassword != text4)
					{
						response.Reason = text3 + "You have entered an incorrect password.";
						response.Approved = false;
					}
				}
				else
				{
					response.Reason = text3 + "This lobby is password protected which requires you to have the LobbyImprovements mod.";
					response.Approved = false;
				}
			}
			if (__instance.disableSteam)
			{
				if (!response.Approved)
				{
					return;
				}
				if (array.Any((string x) => x.StartsWith("playername:")))
				{
					string playerName = array.First((string x) => x.StartsWith("playername:")).Substring(11);
					lanPlayer.playerName = playerName;
				}
				PlayerManager.sv_lanPlayers.Add(lanPlayer);
			}
			else
			{
				if (!response.Approved)
				{
					return;
				}
				ulong num = (ulong)Convert.ToInt64(array[1]);
				if (array.Any((string x) => x.StartsWith("ticket:")) && PluginLoader.steamSecureLobby)
				{
					response.Pending = true;
					BeginAuthResult val = (BeginAuthResult)1;
					try
					{
						val = SteamUser.BeginAuthSession(Array.ConvertAll(array.First((string x) => x.StartsWith("ticket:")).Substring(7).Split(';'), byte.Parse), SteamId.op_Implicit(num));
					}
					catch (Exception ex)
					{
						PluginLoader.StaticLogger.LogError((object)ex);
					}
					PluginLoader.StaticLogger.LogInfo((object)$"[Steam] ConnectionApproval ({num}): {val}");
					if ((int)val != 0 && PluginLoader.steamSecureLobby)
					{
						string arg = "<size=12><color=red>Invalid Steam Ticket:<color=white>\n";
						response.Reason = $"{arg}{val}";
						response.Approved = false;
					}
					else
					{
						ulong clientId2 = request.ClientNetworkId;
						if (!PlayerManager.sv_steamPlayers.Any((SV_SteamPlayer t) => t.actualClientId == clientId2))
						{
							PlayerManager.sv_steamPlayers.Add(new SV_SteamPlayer
							{
								actualClientId = clientId2,
								steamId = SteamId.op_Implicit(num),
								authResult1 = (LIBeginAuthResult)val
							});
						}
					}
					response.Pending = false;
				}
				else if (PluginLoader.steamSecureLobby)
				{
					PluginLoader.StaticLogger.LogInfo((object)$"[Steam] ConnectionApproval ({num}): MissingTicket");
					string text5 = "<size=12><color=red>Missing Steam Ticket:<color=white>\n";
					response.Reason = text5 + "This lobby requires you to have the LobbyImprovements mod.";
					response.Approved = false;
				}
				else
				{
					ulong clientId = request.ClientNetworkId;
					if (!PlayerManager.sv_steamPlayers.Any((SV_SteamPlayer t) => t.actualClientId == clientId))
					{
						PlayerManager.sv_steamPlayers.Add(new SV_SteamPlayer
						{
							actualClientId = clientId,
							steamId = SteamId.op_Implicit(num)
						});
					}
				}
			}
		}

		[HarmonyPatch(typeof(LobbyQuery), "ApplyFilters")]
		[HarmonyPrefix]
		public static void ApplyFilters_Prefix(ref LobbyQuery __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				((LobbyQuery)(ref __instance)).WithLower("maxplayers", 5);
			}
		}
	}
	[HarmonyPatch]
	public class RecentlyPlayedWith
	{
		internal static HashSet<ulong> PlayerList = new HashSet<ulong>();

		internal static bool initialJoin = true;

		internal static void SetPlayedWith(ulong[] playerSteamIds, string debugType)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			playerSteamIds = playerSteamIds.Where((ulong x) => (float)x != 0f && x != SteamId.op_Implicit(SteamClient.SteamId) && (debugType == "generateLevel" || !PlayerList.Contains(x))).ToArray();
			if (playerSteamIds.Length == 0)
			{
				return;
			}
			ulong[] array = playerSteamIds;
			foreach (ulong num in array)
			{
				if (!PlayerList.Contains(num))
				{
					PlayerList.Add(num);
				}
				SteamFriends.SetPlayedWith(SteamId.op_Implicit(num));
			}
			PluginLoader.StaticLogger.LogInfo((object)$"Set recently played with ({debugType}) for {playerSteamIds.Length} players.");
			PluginLoader.StaticLogger.LogDebug((object)("Set recently played with (" + debugType + "): " + string.Join(", ", playerSteamIds)));
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void GenerateNewLevelClientRpc(ref RoundManager __instance)
		{
			SetPlayedWith((from x in __instance.playersManager.allPlayerScripts
				where x.isPlayerControlled || x.isPlayerDead
				select x.playerSteamId).ToArray(), "generateLevel");
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SendNewPlayerValuesClientRpc")]
		[HarmonyPostfix]
		private static void PlayerControllerB_SendNewPlayerValuesClientRpc(ref ulong[] playerSteamIds)
		{
			if ((Object)(object)StartOfRound.Instance != (Object)null && (!StartOfRound.Instance.inShipPhase || PluginLoader.recentlyPlayedWithOrbit.Value))
			{
				string debugType = "otherJoined";
				if (initialJoin)
				{
					initialJoin = false;
					debugType = "selfJoined";
				}
				SetPlayedWith(playerSteamIds.ToArray(), debugType);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
		[HarmonyPostfix]
		private static void StartOfRound_OnPlayerDC(ref StartOfRound __instance, ref int playerObjectNumber, ulong clientId)
		{
			ulong playerSteamId = __instance.allPlayerScripts[playerObjectNumber].playerSteamId;
			PlayerList.Remove(playerSteamId);
			PluginLoader.StaticLogger.LogInfo((object)$"Removing {playerSteamId} from recently played with.");
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDestroy")]
		[HarmonyPostfix]
		private static void StartOfRound_OnDestroy()
		{
			initialJoin = true;
			if (PlayerList.Count > 0)
			{
				PlayerList.Clear();
				PluginLoader.StaticLogger.LogInfo((object)"Cleared recently played with (OnDestroy)");
			}
		}
	}
	[HarmonyPatch]
	public class SessionTickets_Hosting
	{
		internal static void BroadcastPlayerInfoToClients(SV_SteamPlayer sv_playerInfo)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			string text = JsonConvert.SerializeObject((object)new CL_SteamPlayer
			{
				actualClientId = sv_playerInfo.actualClientId,
				authResult1 = (LIMinimalAuthResult)((sv_playerInfo.authResult1 >= LIBeginAuthResult.InvalidTicket) ? LIBeginAuthResult.InvalidTicket : sv_playerInfo.authResult1),
				authResult2 = (LIMinimalAuthResult)((sv_playerInfo.authResult2 >= LIAuthResponse.UserNotConnectedToSteam) ? LIAuthResponse.UserNotConnectedToSteam : sv_playerInfo.authResult2)
			});
			int writeSize = FastBufferWriter.GetWriteSize(text, false);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(writeSize, (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("LI_CL_ReceivePlayerInfo", val, (NetworkDelivery)((((FastBufferWriter)(ref val)).Capacity > 1300) ? 4 : 2));
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		internal static void BroadcastPlayerInfoToClients(SV_LANPlayer sv_playerInfo)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			string text = JsonConvert.SerializeObject((object)new CL_LANPlayer
			{
				actualClientId = sv_playerInfo.actualClientId,
				playerName = sv_playerInfo.playerName
			});
			int writeSize = FastBufferWriter.GetWriteSize(text, false);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(writeSize, (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("LI_CL_ReceivePlayerInfo", val, (NetworkDelivery)((((FastBufferWriter)(ref val)).Capacity > 1300) ? 4 : 2));
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		internal static void BroadcastAllPlayerInfoToClient(ulong clientId)
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val2;
			if (GameNetworkManager.Instance.disableSteam)
			{
				List<CL_LANPlayer> list = new List<CL_LANPlayer>();
				foreach (SV_LANPlayer sv_lanPlayer in PlayerManager.sv_lanPlayers)
				{
					list.Add(new CL_LANPlayer
					{
						actualClientId = sv_lanPlayer.actualClientId,
						playerName = sv_lanPlayer.playerName
					});
				}
				string text = JsonConvert.SerializeObject((object)list);
				int writeSize = FastBufferWriter.GetWriteSize(text, false);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(writeSize, (Allocator)2, -1);
				val2 = val;
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LI_CL_ReceiveAllPlayerInfo", clientId, val, (NetworkDelivery)((((FastBufferWriter)(ref val)).Capacity > 1300) ? 4 : 2));
					return;
				}
				finally
				{
					((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
				}
			}
			List<CL_SteamPlayer> list2 = new List<CL_SteamPlayer>();
			foreach (SV_SteamPlayer sv_steamPlayer in PlayerManager.sv_steamPlayers)
			{
				list2.Add(new CL_SteamPlayer
				{
					actualClientId = sv_steamPlayer.actualClientId,
					authResult1 = (LIMinimalAuthResult)((sv_steamPlayer.authResult1 >= LIBeginAuthResult.InvalidTicket) ? LIBeginAuthResult.InvalidTicket : sv_steamPlayer.authResult1),
					authResult2 = (LIMinimalAuthResult)((sv_steamPlayer.authResult2 >= LIAuthResponse.UserNotConnectedToSteam) ? LIAuthResponse.UserNotConnectedToSteam : sv_steamPlayer.authResult2)
				});
			}
			string text2 = JsonConvert.SerializeObject((object)list2);
			int writeSize2 = FastBufferWriter.GetWriteSize(text2, false);
			FastBufferWriter val3 = default(FastBufferWriter);
			((FastBufferWriter)(ref val3))..ctor(writeSize2, (Allocator)2, -1);
			val2 = val3;
			try
			{
				((FastBufferWriter)(ref val3)).WriteValueSafe(text2, false);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LI_CL_ReceiveAllPlayerInfo", clientId, val3, (NetworkDelivery)((((FastBufferWriter)(ref val3)).Capacity > 1300) ? 4 : 2));
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		public static void SteamUser_OnValidateAuthTicketResponse(SteamId steamId, SteamId steamIdOwner, AuthResponse response)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected I4, but got Unknown
			//IL_0059: 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)
			if ((int)response != 6)
			{
				PluginLoader.StaticLogger.LogInfo((object)$"[Steam] OnValidateAuthTicketResponse ({steamId}): {response}");
			}
			string arg = "<size=12><color=red>Invalid Steam Ticket:<color=white>\n";
			foreach (SV_SteamPlayer sv_steamPlayer in PlayerManager.sv_steamPlayers)
			{
				if (SteamId.op_Implicit(steamId) == SteamId.op_Implicit(sv_steamPlayer.steamId))
				{
					sv_steamPlayer.authResult2 = (LIAuthResponse)response;
					if ((int)response != 0 && PluginLoader.steamSecureLobby && sv_steamPlayer.actualClientId != 0L)
					{
						NetworkManager.Singleton.DisconnectClient(sv_steamPlayer.actualClientId, $"{arg}{response}");
					}
					else
					{
						BroadcastPlayerInfoToClients(sv_steamPlayer);
					}
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "OnEnable")]
		[HarmonyPostfix]
		private static void GNM_OnEnable(GameNetworkManager __instance)
		{
			if (!__instance.disableSteam)
			{
				SteamUser.OnValidateAuthTicketResponse += SteamUser_OnValidateAuthTicketResponse;
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "OnDisable")]
		[HarmonyPostfix]
		private static void GNM_OnDisable(GameNetworkManager __instance)
		{
			if (!__instance.disableSteam)
			{
				SteamUser.OnValidateAuthTicketResponse -= SteamUser_OnValidateAuthTicketResponse;
			}
		}
	}
	[HarmonyPatch]
	public class SessionTickets_Client
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__CL_ReceivePlayerInfo;

			public static HandleNamedMessageDelegate <1>__CL_ReceiveAllPlayerInfo;

			public static HandleNamedMessageDelegate <2>__SV_RequestAllPlayerInfo;
		}

		internal static AuthTicket currentTicket;

		private static Color profileIconColor = Color.clear;

		internal static string ParsePlayerName(string playerName, int playerClientId)
		{
			string input = GameNetworkManager.Instance.NoPunctuation(playerName ?? "");
			input = Regex.Replace(input, "[^\\w\\._]", "");
			if (input == string.Empty || input.Length == 0)
			{
				input = $"Player #{playerClientId}";
			}
			else if (input.Length <= 2)
			{
				input += "0";
			}
			else if (input.Length > 32)
			{
				input = input.Substring(0, 32);
			}
			return input;
		}

		internal static void UpdatedPlayerInfo(CL_LANPlayer playerInfo)
		{
			if (GameNetworkManager.Instance.disableSteam && StartOfRound.Instance.ClientPlayerList.TryGetValue(playerInfo.actualClientId, out var value) && playerInfo.playerName != StartOfRound.Instance.allPlayerScripts[value].playerUsername)
			{
				string text = ParsePlayerName(playerInfo.playerName, value);
				StartOfRound.Instance.allPlayerScripts[value].playerUsername = text;
				((TMP_Text)StartOfRound.Instance.allPlayerScripts[value].usernameBillboardText).text = text;
				string text2 = text;
				int numberOfDuplicateNamesInLobby = StartOfRound.Instance.allPlayerScripts[value].GetNumberOfDuplicateNamesInLobby();
				if (numberOfDuplicateNamesInLobby > 0)
				{
					text2 = $"{text}{numberOfDuplicateNamesInLobby}";
				}
				QuickMenuManager val = Object.FindFirstObjectByType<QuickMenuManager>();
				if (Object.op_Implicit((Object)(object)val) && value < val.playerListSlots.Length)
				{
					((TMP_Text)val.playerListSlots[value].usernameHeader).text = text2;
				}
				StartOfRound.Instance.mapScreen.radarTargets[value].name = text2;
			}
		}

		internal static void UpdatedPlayerInfo(CL_SteamPlayer playerInfo)
		{
			//IL_003d: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if (GameNetworkManager.Instance.disableSteam || !StartOfRound.Instance.ClientPlayerList.TryGetValue(playerInfo.actualClientId, out var value))
			{
				return;
			}
			QuickMenuManager val = Object.FindFirstObjectByType<QuickMenuManager>();
			if (value >= val.playerListSlots.Length)
			{
				return;
			}
			Color val2 = ((profileIconColor != Color.clear) ? profileIconColor : Color.clear);
			if (playerInfo.authResult1 == LIMinimalAuthResult.OK && playerInfo.authResult2 == LIMinimalAuthResult.OK)
			{
				((Color)(ref val2))..ctor(0f, 0.5f, 0.3f, 1f);
			}
			else if (playerInfo.authResult1 == LIMinimalAuthResult.Invalid || playerInfo.authResult2 == LIMinimalAuthResult.Invalid)
			{
				val2 = Color.red;
			}
			if (!(val2 != Color.clear))
			{
				return;
			}
			PlayerListSlot obj = val.playerListSlots[value];
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				GameObject slotContainer = obj.slotContainer;
				if (slotContainer == null)
				{
					obj2 = null;
				}
				else
				{
					Transform transform = slotContainer.transform;
					if (transform == null)
					{
						obj2 = null;
					}
					else
					{
						Transform obj3 = transform.Find("ProfileIcon");
						obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
					}
				}
			}
			Image val3 = (Image)obj2;
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (profileIconColor == Color.clear)
				{
					profileIconColor = ((Graphic)val3).color;
				}
				((Graphic)val3).color = val2;
			}
		}

		internal static void CL_ReceivePlayerInfo(ulong senderId, FastBufferReader messagePayload)
		{
			string text = default(string);
			((FastBufferReader)(ref messagePayload)).ReadValueSafe(ref text, false);
			if (GameNetworkManager.Instance.disableSteam)
			{
				CL_LANPlayer playerInfo = JsonConvert.DeserializeObject<CL_LANPlayer>(text);
				int num = PlayerManager.cl_lanPlayers.FindIndex((CL_LANPlayer x) => x.actualClientId == playerInfo.actualClientId);
				if (num != -1)
				{
					PlayerManager.cl_lanPlayers[num] = playerInfo;
				}
				else
				{
					PlayerManager.cl_lanPlayers.Add(playerInfo);
				}
				UpdatedPlayerInfo(playerInfo);
			}
			else
			{
				CL_SteamPlayer playerInfo2 = JsonConvert.DeserializeObject<CL_SteamPlayer>(text);
				int num2 = PlayerManager.cl_steamPlayers.FindIndex((CL_SteamPlayer x) => x.actualClientId == playerInfo2.actualClientId);
				if (num2 != -1)
				{
					PlayerManager.cl_steamPlayers[num2] = playerInfo2;
				}
				else
				{
					PlayerManager.cl_steamPlayers.Add(playerInfo2);
				}
				UpdatedPlayerInfo(playerInfo2);
			}
		}

		internal static void CL_ReceiveAllPlayerInfo(ulong senderId, FastBufferReader messagePayload)
		{
			string text = default(string);
			((FastBufferReader)(ref messagePayload)).ReadValueSafe(ref text, false);
			if (GameNetworkManager.Instance.disableSteam)
			{
				PlayerManager.cl_lanPlayers = JsonConvert.DeserializeObject<List<CL_LANPlayer>>(text);
				{
					foreach (CL_LANPlayer cl_lanPlayer in PlayerManager.cl_lanPlayers)
					{
						UpdatedPlayerInfo(cl_lanPlayer);
					}
					return;
				}
			}
			PlayerManager.cl_steamPlayers = JsonConvert.DeserializeObject<List<CL_SteamPlayer>>(text);
			foreach (CL_SteamPlayer cl_steamPlayer in PlayerManager.cl_steamPlayers)
			{
				UpdatedPlayerInfo(cl_steamPlayer);
			}
		}

		internal static void SV_RequestAllPlayerInfo(ulong senderId, FastBufferReader messagePayload)
		{
			if (GameNetworkManager.Instance.disableSteam)
			{
				SV_LANPlayer sV_LANPlayer = PlayerManager.sv_lanPlayers.Find((SV_LANPlayer x) => x.actualClientId == senderId);
				if (sV_LANPlayer != null)
				{
					SessionTickets_Hosting.BroadcastPlayerInfoToClients(sV_LANPlayer);
				}
			}
			else
			{
				SV_SteamPlayer sV_SteamPlayer = PlayerManager.sv_steamPlayers.Find((SV_SteamPlayer x) => x.actualClientId == senderId);
				if (sV_SteamPlayer != null)
				{
					SessionTickets_Hosting.BroadcastPlayerInfoToClients(sV_SteamPlayer);
				}
			}
			SessionTickets_Hosting.BroadcastAllPlayerInfoToClient(senderId);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPrefix]
		private static void ConnectClientToPlayerObject_Prefix(PlayerControllerB __instance)
		{
			//IL_001f: 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_002a: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0089: 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_0094: Expected O, but got Unknown
			CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
			object obj = <>O.<0>__CL_ReceivePlayerInfo;
			if (obj == null)
			{
				HandleNamedMessageDelegate val = CL_ReceivePlayerInfo;
				<>O.<0>__CL_ReceivePlayerInfo = val;
				obj = (object)val;
			}
			customMessagingManager.RegisterNamedMessageHandler("LI_CL_ReceivePlayerInfo", (HandleNamedMessageDelegate)obj);
			CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
			object obj2 = <>O.<1>__CL_ReceiveAllPlayerInfo;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = CL_ReceiveAllPlayerInfo;
				<>O.<1>__CL_ReceiveAllPlayerInfo = val2;
				obj2 = (object)val2;
			}
			customMessagingManager2.RegisterNamedMessageHandler("LI_CL_ReceiveAllPlayerInfo", (HandleNamedMessageDelegate)obj2);
			if (NetworkManager.Singleton.IsHost)
			{
				CustomMessagingManager customMessagingManager3 = NetworkManager.Singleton.CustomMessagingManager;
				object obj3 = <>O.<2>__SV_RequestAllPlayerInfo;
				if (obj3 == null)
				{
					HandleNamedMessageDelegate val3 = SV_RequestAllPlayerInfo;
					<>O.<2>__SV_RequestAllPlayerInfo = val3;
					obj3 = (object)val3;
				}
				customMessagingManager3.RegisterNamedMessageHandler("LI_SV_RequestAllPlayerInfo", (HandleNamedMessageDelegate)obj3);
			}
			PluginLoader.StaticLogger.LogInfo((object)"Registered Named Message Handlers");
			if (GameNetworkManager.Instance.disableSteam)
			{
				__instance.playerUsername = ParsePlayerName(PluginLoader.lanPlayerName, (int)__instance.playerClientId);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void ConnectClientToPlayerObject_Postfix(PlayerControllerB __instance)
		{
			//IL_0173: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost)
			{
				if (GameNetworkManager.Instance.disableSteam)
				{
					string text = ParsePlayerName(PluginLoader.lanPlayerName, (int)__instance.playerClientId);
					__instance.playerUsername = text;
					((TMP_Text)__instance.usernameBillboardText).text = text;
					string text2 = text;
					int numberOfDuplicateNamesInLobby = __instance.GetNumberOfDuplicateNamesInLobby();
					if (numberOfDuplicateNamesInLobby > 0)
					{
						text2 = $"{text}{numberOfDuplicateNamesInLobby}";
					}
					__instance.quickMenuManager.AddUserToPlayerList(0uL, text2, (int)__instance.playerClientId);
					StartOfRound.Instance.mapScreen.radarTargets[(int)__instance.playerClientId].name = text2;
					if (!PlayerManager.sv_lanPlayers.Any((SV_LANPlayer t) => t.actualClientId == __instance.actualClientId))
					{
						SV_LANPlayer item = new SV_LANPlayer
						{
							actualClientId = __instance.actualClientId,
							playerName = PluginLoader.lanPlayerName
						};
						PlayerManager.sv_lanPlayers.Add(item);
					}
				}
				else if (!PlayerManager.sv_steamPlayers.Any((SV_SteamPlayer t) => t.actualClientId == __instance.actualClientId))
				{
					SV_SteamPlayer item2 = new SV_SteamPlayer
					{
						actualClientId = __instance.actualClientId,
						steamId = SteamId.op_Implicit(__instance.playerSteamId)
					};
					PlayerManager.sv_steamPlayers.Add(item2);
				}
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1);
			FastBufferWriter val2 = val;
			try
			{
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LI_SV_RequestAllPlayerInfo", 0uL, val, (NetworkDelivery)((((FastBufferWriter)(ref val)).Capacity > 1300) ? 4 : 2));
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val2)).Dispose();
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SetInstanceValuesBackToDefault")]
		[HarmonyPostfix]
		public static void SetInstanceValuesBackToDefault()
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.CustomMessagingManager != null)
			{
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("LI_CL_ReceivePlayerInfo");
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("LI_CL_ReceiveAllPlayerInfo");
				NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("LI_SV_RequestAllPlayerInfo");
				PluginLoader.StaticLogger.LogInfo((object)"Unregistered Named Message Handlers");
			}
		}

		[HarmonyPatch(typeof(QuickMenuManager), "AddUserToPlayerList")]
		[HarmonyPostfix]
		public static void AddUserToPlayerList(ulong steamId, int playerObjectId)
		{
			if (GameNetworkManager.Instance.disableSteam)
			{
				PluginLoader.StaticLogger.LogInfo((object)("Adding user to player list: " + playerObjectId));
				CL_LANPlayer cL_LANPlayer = PlayerManager.cl_lanPlayers.Find((CL_LANPlayer x) => x.actualClientId == StartOfRound.Instance.allPlayerScripts[playerObjectId].actualClientId);
				if (cL_LANPlayer != null)
				{
					PluginLoader.StaticLogger.LogInfo((object)("Adding user to player list (UpdatedPlayerInfo): " + playerObjectId));
					UpdatedPlayerInfo(cL_LANPlayer);
				}
			}
			else
			{
				CL_SteamPlayer cL_SteamPlayer = PlayerManager.cl_steamPlayers.Find((CL_SteamPlayer x) => x.actualClientId == StartOfRound.Instance.allPlayerScripts[playerObjectId].actualClientId);
				if (cL_SteamPlayer != null)
				{
					UpdatedPlayerInfo(cL_SteamPlayer);
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		[HarmonyPrefix]
		private static void StartDisconnect(GameNetworkManager __instance)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.disableSteam)
			{
				AuthTicket obj = currentTicket;
				if (obj != null)
				{
					obj.Cancel();
				}
				foreach (SV_SteamPlayer sv_steamPlayer in PlayerManager.sv_steamPlayers)
				{
					SteamUser.EndAuthSession(sv_steamPlayer.steamId);
				}
			}
			PlayerManager.cl_lanPlayers.Clear();
			PlayerManager.cl_steamPlayers.Clear();
			PlayerManager.sv_lanPlayers.Clear();
			PlayerManager.sv_steamPlayers.Clear();
		}

		[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
		[HarmonyPrefix]
		private static void OnPlayerDC(ulong clientId)
		{
			//IL_003e: 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)
			if (!GameNetworkManager.Instance.disableSteam)
			{
				SV_SteamPlayer sV_SteamPlayer = PlayerManager.sv_steamPlayers.Find((SV_SteamPlayer x) => x.actualClientId == clientId);
				if (sV_SteamPlayer != null)
				{
					PluginLoader.StaticLogger.LogInfo((object)$"[SteamUser.EndAuthSession] {sV_SteamPlayer.steamId}");
					SteamUser.EndAuthSession(sV_SteamPlayer.steamId);
					PlayerManager.sv_steamPlayers.Remove(sV_SteamPlayer);
				}
			}
			else
			{
				SV_LANPlayer sV_LANPlayer = PlayerManager.sv_lanPlayers.Find((SV_LANPlayer x) => x.actualClientId == clientId && !x.banned);
				if (sV_LANPlayer != null)
				{
					PlayerManager.sv_lanPlayers.Remove(sV_LANPlayer);
				}
			}
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "uk.1a3.lobbyimprovements";

		public const string PLUGIN_NAME = "LobbyImprovements";

		public const string PLUGIN_VERSION = "1.0.7";
	}
}
namespace LobbyImprovements.LANDiscovery
{
	[Serializable]
	public class LANLobby
	{
		public string GameId;

		public string GameVersion;

		public string IPAddress;

		public ushort Port;

		public string LobbyName;

		public string LobbyTag = "none";

		public int MemberCount;

		public int MaxMembers;

		public bool IsChallengeMoon;

		public bool IsSecure;

		public bool IsPasswordProtected;

		public string Mods;
	}
	public class ClientDiscovery
	{
		private UdpClient udpClient;

		private CancellationTokenSource cancellationTokenSource;

		private int listenPort;

		private List<LANLobby> discoveredLobbies = new List<LANLobby>();

		public bool isListening { get; private set; }

		private async Task<LANLobby> StartListening(string targetLobbyIP, int targetLobbyPort, float maxDiscoveryTime, CancellationToken cancellationToken)
		{
			_ = 1;
			try
			{
				Task timeoutTask = Task.Delay(TimeSpan.FromSeconds(maxDiscoveryTime), cancellationToken);
				while (!cancellationToken.IsCancellationRequested)
				{
					Task<UdpReceiveResult> task = udpClient.ReceiveAsync();
					if (await Task.WhenAny(new Task[2] { task, timeoutTask }) == task)
					{
						UdpReceiveResult udpReceiveResult = await task;
						byte[] buffer = udpReceiveResult.Buffer;
						string @string = Encoding.UTF8.GetString(buffer);
						LANLobby lANLobby = ParseAndStoreLobby(udpReceiveResult.RemoteEndPoint.Address.ToString(), @string, targetLobbyIP, targetLobbyPort);
						if (lANLobby != null)
						{
							return lANLobby;
						}
						continue;
					}
					return null;
				}
			}
			catch (Exception ex)
			{
				PluginLoader.StaticLogger.LogError((object)("[LAN Discovery] StartListening Error: " + ex.Message));
			}
			return null;
		}

		public async Task<LANLobby> DiscoverSpecificLobbyAsync(string targetLobbyIP, int targetLobbyPort, float discoveryTime)
		{
			if (isListening)
			{
				cancellationTokenSource.Cancel();
				await Task.Delay(100);
			}
			try
			{
				PluginLoader.StaticLogger.LogInfo((object)$"[LAN Discovery] DiscoverSpecificLobbyAsync Started (Target: {targetLobbyIP}:{targetLobbyPort})");
				udpClient?.Dispose();
				listenPort = PluginLoader.lanDiscoveryPort.Value;
				udpClient = new UdpClient(listenPort);
				cancellationTokenSource = new CancellationTokenSource();
				isListening = true;
				return await StartListening(targetLobbyIP, targetLobbyPort, discoveryTime, cancellationTokenSource.Token);
			}
			catch (Exception arg)
			{
				PluginLoader.StaticLogger.LogError((object)$"[LAN Discovery] DiscoverSpecificLobbyAsync Error: {arg}");
			}
			finally
			{
				udpClient?.Close();
				isListening = false;
				PluginLoader.StaticLogger.LogInfo((object)$"[LAN Discovery] DiscoverSpecificLobbyAsync Stopped (Target: {targetLobbyIP}:{targetLobbyPort})");
			}
			return null;
		}

		public async Task<List<LANLobby>> DiscoverLobbiesAsync(float discoveryTime)
		{
			if (isListening)
			{
				cancellationTokenSource.Cancel();
				await Task.Delay(100);
			}
			try
			{
				PluginLoader.StaticLogger.LogInfo((object)"[LAN Discovery] DiscoverLobbiesAsync Started");
				udpClient?.Dispose();
				listenPort = PluginLoader.lanDiscoveryPort.Value;
				udpClient = new UdpClient(listenPort);
				cancellationTokenSource = new CancellationTokenSource();
				isListening = true;
				discoveredLobbies.Clear();
				await StartListening(null, 0, discoveryTime, cancellationTokenSource.Token);
			}
			catch (Exception ex)
			{
				PluginLoader.StaticLogger.LogError((object)("[LAN Discovery] DiscoverLobbiesAsync Error: " + ex));
			}
			finally
			{
				udpClient?.Close();
				isListening = false;
				PluginLoader.StaticLogger.LogInfo((object)"[LAN Discovery] DiscoverLobbiesAsync Stopped");
			}
			return discoveredLobbies;
		}

		private LANLobby ParseAndStoreLobby(string ipAddress, string message, string targetLobbyIP, int targetLobbyPort)
		{
			try
			{
				LANLobby parsedLobby = JsonUtility.FromJson<LANLobby>(message);
				if (parsedLobby != null && parsedLobby.GameId == LANLobbyManager_LobbyList.DiscoveryKey && parsedLobby.GameVersion == GameNetworkManager.Instance.gameVersionNum.ToString())
				{
					parsedLobby.IPAddress = ipAddress;
					if (targetLobbyIP != null)
					{
						return (parsedLobby.IPAddress == targetLobbyIP && parsedLobby.Port == targetLobbyPort) ? parsedLobby : null;
					}
					LANLobby lANLobby = discoveredLobbies.Find((LANLobby lobby) => lobby.IPAddress == parsedLobby.IPAddress && lobby.Port == parsedLobby.Port);
					if (lANLobby != null)
					{
						lANLobby.MemberCount = parsedLobby.MemberCount;
					}
					else
					{
						discoveredLobbies.Add(parsedLobby);
						PluginLoader.StaticLogger.LogInfo((object)$"[LAN Discovery] Discovered Lobby: {parsedLobby.LobbyName} at {parsedLobby.IPAddress}:{parsedLobby.Port} with {parsedLobby.MemberCount}/{parsedLobby.MaxMembers} players.");
					}
				}
			}
			catch (Exception ex)
			{
				PluginLoader.StaticLogger.LogError((object)ex);
			}
			return null;
		}
	}
	[HarmonyPatch]
	public static class LANLobbyManager_LobbyList
	{
		public static string DiscoveryKey = "1966720_LobbyImprovements";

		internal static LANLobby[] currentLobbyList;

		internal static ClientDiscovery clientDiscovery;

		private static bool lanWarningShown;

		[HarmonyPatch(typeof(MenuManager), "Start")]
		[HarmonyPostfix]
		private static void MenuManager_Start(MenuManager __instance)
		{
			if (__instance.isInitScene || !GameNetworkManager.Instance.disableSteam)
			{
				return;
			}
			GameObject lanButtonContainer = __instance.lanButtonContainer;
			if (lanButtonContainer != null)
			{
				lanButtonContainer.SetActive(false);
			}
			GameObject joinCrewButtonContainer = __instance.joinCrewButtonContainer;
			if (joinCrewButtonContainer != null)
			{
				joinCrewButtonContainer.SetActive(true);
			}
			if (lanWarningShown)
			{
				GameObject lanWarningContainer = __instance.lanWarningContainer;
				if (lanWarningContainer != null)
				{
					lanWarningContainer.SetActive(false);
				}
			}
			else
			{
				lanWarningShown = true;
			}
		}

		[HarmonyPatch(typeof(SteamLobbyManager), "LoadServerList")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool SteamLobbyManager_LoadServerList(SteamLobbyManager __instance)
		{
			//IL_00b0: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			if (GameNetworkManager.Instance.disableSteam)
			{
				GameObject obj = GameObject.Find("LobbyList/ListPanel/SortPlayerCountButton");
				if (obj != null)
				{
					obj.SetActive(false);
				}
				GameObject obj2 = GameObject.Find("LobbyList/ListPanel/Dropdown");
				if (obj2 != null)
				{
					obj2.SetActive(false);
				}
				Transform obj3 = ((Component)__instance.serverTagInputField).transform.parent.Find("PlayerNameInputField");
				TMP_InputField val = ((obj3 != null) ? ((Component)obj3).gameObject.GetComponent<TMP_InputField>() : null);
				if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)__instance.serverTagInputField).gameObject, ((Component)__instance.serverTagInputField).transform.parent);
					((Object)val2).name = "PlayerNameInputField";
					val2.transform.localPosition = new Vector3(225f, val2.transform.localPosition.y, val2.transform.localPosition.z);
					val = val2.GetComponent<TMP_InputField>();
					val.characterLimit = 32;
					val.characterValidation = (CharacterValidation)4;
					((TMP_Text)((Component)val.placeholder).gameObject.GetComponent<TextMeshProUGUI>()).text = "Nameless";
					val.onEndEdit = new SubmitEvent();
					((UnityEvent<string>)(object)val.onEndEdit).AddListener((UnityAction<string>)delegate(string s)
					{
						PluginLoader.lanPlayerName = s;
						SaveLoadHandler.SaveData(ModDataHelper.GetModDataKey((object)typeof(PluginLoader), "lanPlayerName"));
					});
				}
				val.text = PluginLoader.lanPlayerName;
				LoadServerList_LAN(__instance);
				return false;
			}
			return true;
		}

		public static async void LoadServerList_LAN(SteamLobbyManager __instance)
		{
			if (GameNetworkManager.Instance.waitingForLobbyDataRefresh)
			{
				return;
			}
			if (clientDiscovery == null)
			{
				clientDiscovery = new ClientDiscovery();
			}
			if (!clientDiscovery.isListening)
			{
				if (__instance.loadLobbyListCoroutine != null)
				{
					((MonoBehaviour)GameNetworkManager.Instance).StopCoroutine(__instance.loadLobbyListCoroutine);
				}
				__instance.refreshServerListTimer = 0f;
				((TMP_Text)__instance.serverListBlankText).text = "Loading server list...";
				((Component)__instance.serverListBlankText).gameObject.SetActive(true);
				currentLobbyList = null;
				LANLobbySlot[] array = Object.FindObjectsByType<LANLobbySlot>((FindObjectsSortMode)1);
				for (int i = 0; i < array.Length; i++)
				{
					Object.Destroy((Object)(object)((Component)array[i]).gameObject);
				}
				string serverTagInputField = __instance.serverTagInputField.text;
				GameNetworkManager.Instance.waitingForLobbyDataRefresh = true;
				currentLobbyList = (await clientDiscovery.DiscoverLobbiesAsync(2f)).ToArray();
				if (currentLobbyList != null && currentLobbyList.Length != 0)
				{
					((TMP_Text)__instance.serverListBlankText).text = "";
					__instance.lobbySlotPositionOffset = 0f;
					__instance.loadLobbyListCoroutine = ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(loadLobbyListAndFilter(currentLobbyList, __instance, serverTagInputField));
				}
				else
				{
					((TMP_Text)__instance.serverListBlankText).text = "No available servers to join.";
					GameNetworkManager.Instance.waitingForLobbyDataRefresh = false;
				}
			}
		}

		private static IEnumerator loadLobbyListAndFilter(LANLobby[] lobbyList, SteamLobbyManager __instance, string serverTagInputField)
		{
			((Component)__instance.serverListBlankText).gameObject.SetActive(false);
			bool anyResults = false;
			Array.Sort(lobbyList, (LANLobby x, LANLobby y) => (x.MemberCount == y.MemberCount) ? ((x.MaxMembers == y.MaxMembers) ? x.LobbyName.CompareTo(y.LobbyName) : (y.MaxMembers - x.MaxMembers)) : (y.MemberCount - x.MemberCount));
			for (int i = 0; i < lobbyList.Length; i++)
			{
				if ((!__instance.sortWithChallengeMoons && lobbyList[i].IsChallengeMoon) || (serverTagInputField != string.Empty && serverTagInputField != lobbyList[i].LobbyTag))
				{
					continue;
				}
				string lobbyName = lobbyList[i].LobbyName;
				if (lobbyName.Length == 0)
				{
					continue;
				}
				string lobbyNameNoCapitals = lobbyName.ToLower();
				if (__instance.censorOffensiveLobbyNames && PluginLoader.lobbyNameParsedBlacklist.Any((string x) => lobbyNameNoCapitals.Contains(x)))
				{
					PluginLoader.StaticLogger.LogInfo((object)("Lobby name is offensive: " + lobbyNameNoCapitals + "; skipping"));
					continue;
				}
				anyResults = true;
				GameObject obj = Object.Instantiate<GameObject>((!lobbyList[i].IsChallengeMoon) ? __instance.LobbySlotPrefab : __instance.LobbySlotPrefabChallenge, __instance.levelListContainer);
				obj.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0f + __instance.lobbySlotPositionOffset);
				__instance.lobbySlotPositionOffset -= 42f;
				LobbySlot componentInChildren = obj.GetComponentInChildren<LobbySlot>();
				LANLobbySlot lANLobbySlot = ((Component)componentInChildren).gameObject.AddComponent<LANLobbySlot>();
				Object.Destroy((Object)(object)componentInChildren);
				List<string> list = new List<string>();
				if (lobbyList[i].IsChallengeMoon)
				{
					Transform obj2 = ((Component)lANLobbySlot).transform.Find("ServerName (1)");
					((LobbySlot)lANLobbySlot).LobbyName = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null);
					Transform obj3 = ((Component)lANLobbySlot).transform.Find("NumPlayers (2)");
					((LobbySlot)lANLobbySlot).playerCount = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null);
					Transform obj4 = ((Component)lANLobbySlot).transform.Find("NumPlayers (1)");
					TextMeshProUGUI obj5 = ((obj4 != null) ? ((Component)obj4).GetComponent<TextMeshProUGUI>() : null);
					if (obj5 != null)
					{
						GameObject gameObject = ((Component)obj5).gameObject;
						if (gameObject != null)
						{
							gameObject.SetActive(false);
						}
					}
					list.Add("<color=purple>CHALLENGE</color>");
				}
				else
				{
					Transform obj6 = ((Component)lANLobbySlot).transform.Find("ServerName");
					((LobbySlot)lANLobbySlot).LobbyName = ((obj6 != null) ? ((Component)obj6).GetComponent<TextMeshProUGUI>() : null);
					Transform obj7 = ((Component)lANLobbySlot).transform.Find("NumPlayers");
					((LobbySlot)lANLobbySlot).playerCount = ((obj7 != null) ? ((Component)obj7).GetComponent<TextMeshProUGUI>() : null);
				}
				if (lobbyList[i].IsPasswordProtected)
				{
					list.Add("<color=yellow>PASSWORD</color>");
				}
				if (lobbyList[i].IsSecure)
				{
					list.Add("<color=green>SECURE</color>");
				}
				GameObject obj8 = Object.Instantiate<GameObject>(((Component)((LobbySlot)lANLobbySlot).playerCount).gameObject, ((Component)lANLobbySlot).transform);
				((Object)obj8).name = "TagsText";
				TextMeshProUGUI val = ((obj8 != null) ? obj8.GetComponent<TextMeshProUGUI>() : null);
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val).transform.localPosition = new Vector3(-25f, -15f, 0f);
					((TMP_Text)val).transform.localScale = new Vector3(1f, 1f, 1f);
					((TMP_Text)val).horizontalAlignment = (HorizontalAlignmentOptions)4;
					((TMP_Text)val).alpha = 0.4f;
					((TMP_Text)val).text = string.Join(", ", list);
				}
				if (Object.op_Implicit((Object)(object)((LobbySlot)lANLobbySlot).LobbyName))
				{
					((TMP_Text)((LobbySlot)lANLobbySlot).LobbyName).text = lobbyName.Substring(0, Mathf.Min(lobbyName.Length, 40));
				}
				if (Object.op_Implicit((Object)(object)((LobbySlot)lANLobbySlot).playerCount))
				{
					((TMP_Text)((LobbySlot)lANLobbySlot).playerCount).text = $"{lobbyList[i].MemberCount} / {lobbyList[i].MaxMembers}";
				}
				Transform obj9 = ((Component)lANLobbySlot).transform.Find("HostName");
				lANLobbySlot.HostName = ((obj9 != null) ? ((Component)obj9).GetComponent<TextMeshProUGUI>() : null);
				if (Object.op_Implicit((Object)(object)lANLobbySlot.HostName))
				{
					((TMP_Text)lANLobbySlot.HostName).transform.localPosition = new Vector3(62f, -18.2f, -4.2f);
					((TMP_Text)((Component)lANLobbySlot.HostName).GetComponent<TextMeshProUGUI>()).text = $"Host: {lobbyList[i].IPAddress}:{lobbyList[i].Port}";
				}
				Transform obj10 = ((Component)lANLobbySlot).transform.Find("JoinButton");
				Button val2 = ((obj10 != null) ? ((Component)obj10).GetComponent<Button>() : null);
				if (Object.op_Implicit((Object)(object)val2) && !