Decompiled source of RoR2DirectConnect v2.0.2

plugins/RoR2DirectConnect/RoR2DirectConnect.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Facepunch.Steamworks;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.Networking;
using RoR2.UI;
using RoR2.UI.MainMenu;
using RoR2DirectConnect.Patches;
using RoR2DirectConnect.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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: AssemblyCompany("RoR2DirectConnect")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+78647a700392973a7aa79369da3a616b7fded764")]
[assembly: AssemblyProduct("RoR2DirectConnect")]
[assembly: AssemblyTitle("RoR2DirectConnect")]
[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 RoR2DirectConnect
{
	public class DirectConnectUI : MonoBehaviour
	{
		private bool _showWindow;

		private int _activeTab;

		private string _platformId = "";

		private string _maxPlayers = "4";

		private string _hostPort = "7777";

		private string _serverPassword = "";

		private string _connectAddress = "";

		private string _connectPort = "7777";

		private string _clientPassword = "";

		private List<string> _recentServers = new List<string>();

		private bool _bypassSteam = true;

		private bool _bypassLobby = true;

		private string _statusMessage = "";

		private Color _statusColor = Color.white;

		private float _statusClearTime;

		private Vector2 _playerListScroll;

		private Texture2D _texBg;

		private Texture2D _texCard;

		private Texture2D _texInput;

		private Texture2D _texInputFocus;

		private Texture2D _texBtnBlue;

		private Texture2D _texBtnBlueHover;

		private Texture2D _texBtnGreen;

		private Texture2D _texBtnGreenHover;

		private Texture2D _texBtnRed;

		private Texture2D _texBtnRedHover;

		private Texture2D _texBtnGray;

		private Texture2D _texBtnGrayHover;

		private Texture2D _texTabActive;

		private Texture2D _texTabInactive;

		private Texture2D _texTabHover;

		private Texture2D _texOverlay;

		private Texture2D _texStatusBar;

		private GUIStyle _sWindow;

		private GUIStyle _sCard;

		private GUIStyle _sTitle;

		private GUIStyle _sHeader;

		private GUIStyle _sLabel;

		private GUIStyle _sSmall;

		private GUIStyle _sInput;

		private GUIStyle _sPassword;

		private GUIStyle _sBtnBlue;

		private GUIStyle _sBtnGreen;

		private GUIStyle _sBtnRed;

		private GUIStyle _sBtnGray;

		private GUIStyle _sTabActive;

		private GUIStyle _sTabInactive;

		private GUIStyle _sStatus;

		private GUIStyle _sToggle;

		private GUIStyle _sIndicator;

		private bool _init;

		private KeyCode _toggleKey = (KeyCode)287;

		private const float WIN_W = 480f;

		private const float WIN_H = 560f;

		private void Start()
		{
			_platformId = Plugin.ConfigPlatformId.Value;
			_bypassSteam = Plugin.ConfigBypassSteamAuth.Value;
			_bypassLobby = Plugin.ConfigBypassLobbyCheck.Value;
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(_toggleKey))
			{
				_showWindow = !_showWindow;
			}
			if (_statusClearTime > 0f && Time.time > _statusClearTime)
			{
				_statusMessage = "";
				_statusClearTime = 0f;
			}
		}

		private void InitOnce()
		{
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: 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_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Expected O, but got Unknown
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Expected O, but got Unknown
			//IL_02e7: Expected O, but got Unknown
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Expected O, but got Unknown
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Expected O, but got Unknown
			//IL_0327: Expected O, but got Unknown
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Expected O, but got Unknown
			//IL_03b4: Expected O, but got Unknown
			//IL_03bf: 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_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Expected O, but got Unknown
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Expected O, but got Unknown
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Expected O, but got Unknown
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Expected O, but got Unknown
			//IL_04de: Expected O, but got Unknown
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Expected O, but got Unknown
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0601: Unknown result type (might be due to invalid IL or missing references)
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Expected O, but got Unknown
			//IL_061c: Expected O, but got Unknown
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Expected O, but got Unknown
			//IL_0682: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Expected O, but got Unknown
			if (!_init)
			{
				Color c = default(Color);
				((Color)(ref c))..ctor(0.08f, 0.08f, 0.11f, 0.97f);
				Color c2 = default(Color);
				((Color)(ref c2))..ctor(0.14f, 0.14f, 0.18f, 0.95f);
				Color c3 = default(Color);
				((Color)(ref c3))..ctor(0.1f, 0.1f, 0.14f, 1f);
				Color c4 = default(Color);
				((Color)(ref c4))..ctor(0.16f, 0.16f, 0.22f, 1f);
				Color c5 = default(Color);
				((Color)(ref c5))..ctor(0.22f, 0.45f, 0.78f, 1f);
				Color c6 = default(Color);
				((Color)(ref c6))..ctor(0.28f, 0.52f, 0.88f, 1f);
				Color c7 = default(Color);
				((Color)(ref c7))..ctor(0.18f, 0.58f, 0.28f, 1f);
				Color c8 = default(Color);
				((Color)(ref c8))..ctor(0.22f, 0.68f, 0.32f, 1f);
				Color c9 = default(Color);
				((Color)(ref c9))..ctor(0.7f, 0.18f, 0.18f, 1f);
				Color c10 = default(Color);
				((Color)(ref c10))..ctor(0.82f, 0.22f, 0.22f, 1f);
				Color c11 = default(Color);
				((Color)(ref c11))..ctor(0.28f, 0.28f, 0.32f, 1f);
				Color c12 = default(Color);
				((Color)(ref c12))..ctor(0.35f, 0.35f, 0.4f, 1f);
				Color c13 = default(Color);
				((Color)(ref c13))..ctor(0.22f, 0.45f, 0.78f, 1f);
				Color c14 = default(Color);
				((Color)(ref c14))..ctor(0.18f, 0.18f, 0.22f, 1f);
				Color c15 = default(Color);
				((Color)(ref c15))..ctor(0.24f, 0.24f, 0.3f, 1f);
				Color c16 = default(Color);
				((Color)(ref c16))..ctor(0f, 0f, 0f, 0.55f);
				Color c17 = default(Color);
				((Color)(ref c17))..ctor(0.1f, 0.1f, 0.14f, 0.9f);
				_texBg = Tex(c);
				_texCard = Tex(c2);
				_texInput = Tex(c3);
				_texInputFocus = Tex(c4);
				_texBtnBlue = Tex(c5);
				_texBtnBlueHover = Tex(c6);
				_texBtnGreen = Tex(c7);
				_texBtnGreenHover = Tex(c8);
				_texBtnRed = Tex(c9);
				_texBtnRedHover = Tex(c10);
				_texBtnGray = Tex(c11);
				_texBtnGrayHover = Tex(c12);
				_texTabActive = Tex(c13);
				_texTabInactive = Tex(c14);
				_texTabHover = Tex(c15);
				_texOverlay = Tex(c16);
				_texStatusBar = Tex(c17);
				GUIStyle val = new GUIStyle();
				val.normal.background = _texBg;
				val.padding = new RectOffset(0, 0, 0, 0);
				val.border = new RectOffset(0, 0, 0, 0);
				_sWindow = val;
				GUIStyle val2 = new GUIStyle();
				val2.normal.background = _texCard;
				val2.padding = new RectOffset(14, 14, 10, 10);
				val2.margin = new RectOffset(16, 16, 6, 6);
				_sCard = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 20,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val3.normal.textColor = Color.white;
				_sTitle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1
				};
				val4.normal.textColor = new Color(0.65f, 0.82f, 1f);
				val4.margin = new RectOffset(0, 0, 2, 4);
				_sHeader = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13
				};
				val5.normal.textColor = new Color(0.8f, 0.8f, 0.82f);
				_sLabel = val5;
				GUIStyle val6 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11
				};
				val6.normal.textColor = new Color(0.5f, 0.5f, 0.55f);
				_sSmall = val6;
				GUIStyle val7 = new GUIStyle(GUI.skin.textField)
				{
					fontSize = 15,
					alignment = (TextAnchor)3
				};
				val7.normal.background = _texInput;
				val7.normal.textColor = Color.white;
				val7.focused.background = _texInputFocus;
				val7.focused.textColor = Color.white;
				val7.hover.background = _texInputFocus;
				val7.hover.textColor = Color.white;
				val7.padding = new RectOffset(10, 10, 7, 7);
				val7.fixedHeight = 32f;
				val7.margin = new RectOffset(0, 0, 2, 2);
				_sInput = val7;
				_sPassword = new GUIStyle(_sInput);
				_sBtnBlue = MakeBtn(_texBtnBlue, _texBtnBlueHover, 36f);
				_sBtnGreen = MakeBtn(_texBtnGreen, _texBtnGreenHover, 40f);
				_sBtnRed = MakeBtn(_texBtnRed, _texBtnRedHover, 40f);
				_sBtnGray = MakeBtn(_texBtnGray, _texBtnGrayHover, 30f);
				_sTabActive = MakeBtn(_texTabActive, _texTabActive, 34f);
				_sTabActive.fontSize = 14;
				_sTabInactive = MakeBtn(_texTabInactive, _texTabHover, 34f);
				_sTabInactive.fontSize = 14;
				_sTabInactive.normal.textColor = new Color(0.65f, 0.65f, 0.7f);
				_sStatus = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					wordWrap = true,
					padding = new RectOffset(8, 8, 4, 4)
				};
				GUIStyle val8 = new GUIStyle(GUI.skin.toggle)
				{
					fontSize = 13
				};
				val8.normal.textColor = new Color(0.8f, 0.8f, 0.82f);
				val8.onNormal.textColor = new Color(0.45f, 0.95f, 0.5f);
				_sToggle = val8;
				_sIndicator = new GUIStyle(GUI.skin.label)
				{
					fontSize = 12,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_init = true;
			}
		}

		private void OnGUI()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (_showWindow)
			{
				InitOnce();
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_texOverlay);
				float num = ((float)Screen.width - 480f) / 2f;
				float num2 = ((float)Screen.height - 560f) / 2f;
				Rect val = new Rect(num, num2, 480f, 560f);
				GUI.Box(val, GUIContent.none, _sWindow);
				GUILayout.BeginArea(val);
				DrawPanel();
				GUILayout.EndArea();
			}
		}

		private void DrawPanel()
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_0190: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Space(12f);
			GUILayout.Label("DIRECT CONNECT", _sTitle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Host", (_activeTab == 0) ? _sTabActive : _sTabInactive, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
			{
				_activeTab = 0;
			}
			if (GUILayout.Button("Join", (_activeTab == 1) ? _sTabActive : _sTabInactive, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
			{
				_activeTab = 1;
			}
			if (GUILayout.Button("Settings", (_activeTab == 2) ? _sTabActive : _sTabInactive, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }))
			{
				_activeTab = 2;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			switch (_activeTab)
			{
			case 0:
				DrawHostTab();
				break;
			case 1:
				DrawJoinTab();
				break;
			case 2:
				DrawSettingsTab();
				break;
			}
			if (!string.IsNullOrEmpty(_statusMessage))
			{
				GUILayout.Space(4f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Space(16f);
				GUIStyle val = new GUIStyle();
				val.normal.background = _texStatusBar;
				val.padding = new RectOffset(8, 8, 4, 4);
				GUILayout.BeginVertical(val, Array.Empty<GUILayoutOption>());
				_sStatus.normal.textColor = _statusColor;
				GUILayout.Label(_statusMessage, _sStatus, Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
				GUILayout.Space(16f);
				GUILayout.EndHorizontal();
			}
			GUILayout.FlexibleSpace();
			DrawIndicator();
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label("Press F6 to close", _sSmall, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
		}

		private void DrawHostTab()
		{
			GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
			GUILayout.Label("SERVER SETTINGS", _sHeader, Array.Empty<GUILayoutOption>());
			Row("Port", ref _hostPort, 80f);
			Row("Max Players", ref _maxPlayers, 80f);
			PasswordRow("Password", ref _serverPassword);
			GUILayout.Label("Leave empty for no password", _sSmall, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			if (!NetworkServer.active)
			{
				if (GUILayout.Button("START HOST", _sBtnGreen, Array.Empty<GUILayoutOption>()))
				{
					DoHost();
				}
			}
			else
			{
				if (GUILayout.Button("STOP HOST", _sBtnRed, Array.Empty<GUILayoutOption>()))
				{
					DoDisconnect();
				}
				GUILayout.Space(4f);
				int num = (((Object)(object)NetworkManagerSystem.singleton != (Object)null) ? ((NetworkManager)NetworkManagerSystem.singleton).networkPort : 7777);
				int count = NetworkServer.connections.Count;
				GUILayout.Label($"Listening on port {num}  —  {count} connection(s)", _sSmall, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
			if (NetworkServer.active || NetworkClient.active)
			{
				DrawPlayerList();
			}
		}

		private void DrawJoinTab()
		{
			GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
			GUILayout.Label("CONNECT TO SERVER", _sHeader, Array.Empty<GUILayoutOption>());
			GUILayout.Label("IPv4: 192.168.1.100    IPv6: [::1] or [2001:db8::1]", _sSmall, Array.Empty<GUILayoutOption>());
			GUILayout.Space(2f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Address", _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) });
			_connectAddress = GUILayout.TextField(_connectAddress, _sInput, Array.Empty<GUILayoutOption>());
			GUILayout.Label(":", _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(8f) });
			_connectPort = GUILayout.TextField(_connectPort, _sInput, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(65f) });
			GUILayout.EndHorizontal();
			PasswordRow("Password", ref _clientPassword);
			GUILayout.Space(6f);
			if (!NetworkClient.active && !NetworkServer.active)
			{
				if (GUILayout.Button("CONNECT", _sBtnGreen, Array.Empty<GUILayoutOption>()))
				{
					DoConnect();
				}
			}
			else if (GUILayout.Button("DISCONNECT", _sBtnRed, Array.Empty<GUILayoutOption>()))
			{
				DoDisconnect();
			}
			GUILayout.EndVertical();
			if (_recentServers.Count > 0)
			{
				GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
				GUILayout.Label("RECENT", _sHeader, Array.Empty<GUILayoutOption>());
				foreach (string recentServer in _recentServers)
				{
					if (GUILayout.Button(recentServer, _sBtnGray, Array.Empty<GUILayoutOption>()))
					{
						ParseRecent(recentServer);
					}
				}
				GUILayout.EndVertical();
			}
			if (NetworkClient.active)
			{
				DrawPlayerList();
			}
		}

		private void DrawSettingsTab()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
			GUILayout.Label("IDENTITY", _sHeader, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Platform ID — each player must use a different number", _sSmall, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_platformId = GUILayout.TextField(_platformId, _sInput, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("SAVE", _sBtnBlue, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				if (ulong.TryParse(_platformId, out var _))
				{
					Plugin.ConfigPlatformId.Value = _platformId;
					SetStatus("ID saved!", Color.green);
				}
				else
				{
					SetStatus("Invalid! Must be a number.", Color.red);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
			GUILayout.Label("STEAM BYPASS", _sHeader, Array.Empty<GUILayoutOption>());
			bool flag = GUILayout.Toggle(_bypassSteam, "  Bypass Steam Authentication", _sToggle, Array.Empty<GUILayoutOption>());
			if (flag != _bypassSteam)
			{
				_bypassSteam = flag;
				Plugin.ConfigBypassSteamAuth.Value = flag;
			}
			bool flag2 = GUILayout.Toggle(_bypassLobby, "  Bypass Steam Lobby", _sToggle, Array.Empty<GUILayoutOption>());
			if (flag2 != _bypassLobby)
			{
				_bypassLobby = flag2;
				Plugin.ConfigBypassLobbyCheck.Value = flag2;
			}
			GUILayout.Space(4f);
			GUILayout.Label("Both must be ON for direct connect to work without Steam.", _sSmall, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
		}

		private void DrawPlayerList()
		{
			//IL_0027: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(_sCard, Array.Empty<GUILayoutOption>());
			GUILayout.Label("PLAYERS", _sHeader, Array.Empty<GUILayoutOption>());
			_playerListScroll = GUILayout.BeginScrollView(_playerListScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(60f) });
			ReadOnlyCollection<NetworkUser> readOnlyInstancesList = NetworkUser.readOnlyInstancesList;
			if (readOnlyInstancesList.Count == 0)
			{
				GUILayout.Label("No players connected yet.", _sSmall, Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (NetworkUser item in readOnlyInstancesList)
				{
					string text = item.userName ?? "Unknown";
					string text2 = (((NetworkBehaviour)item).isLocalPlayer ? "  (You)" : "");
					GUILayout.Label("  " + text + text2, _sLabel, Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		private void DrawIndicator()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			string text;
			Color textColor = default(Color);
			if (NetworkServer.active && NetworkClient.active)
			{
				text = "HOST  (Server + Client)";
				((Color)(ref textColor))..ctor(0.35f, 0.95f, 0.45f);
			}
			else if (NetworkServer.active)
			{
				text = "SERVER";
				((Color)(ref textColor))..ctor(0.4f, 0.75f, 0.95f);
			}
			else if (NetworkClient.active)
			{
				text = "CONNECTED";
				((Color)(ref textColor))..ctor(0.35f, 0.95f, 0.45f);
			}
			else
			{
				text = "OFFLINE";
				((Color)(ref textColor))..ctor(0.55f, 0.55f, 0.6f);
			}
			_sIndicator.normal.textColor = textColor;
			GUILayout.Label(text, _sIndicator, Array.Empty<GUILayoutOption>());
		}

		private void DoHost()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				SetStatus("NetworkManager not ready.", Color.red);
				return;
			}
			if (NetworkServer.active)
			{
				SetStatus("Server already running.", Color.yellow);
				return;
			}
			if (!int.TryParse(_maxPlayers, out var result) || result < 1 || result > 16)
			{
				result = 4;
			}
			if (!string.IsNullOrEmpty(_platformId))
			{
				Plugin.ConfigPlatformId.Value = _platformId;
			}
			SetConVar("sv_password", _serverPassword);
			if (ushort.TryParse(_hostPort, out var result2))
			{
				SetConVar("sv_port", result2.ToString());
			}
			NetworkManagerSystem.singleton.desiredHost = new HostDescription(new HostingParameters
			{
				listen = true,
				maxPlayers = result
			});
			string arg = (string.IsNullOrEmpty(_serverPassword) ? "no password" : "password set");
			SetStatus($"Hosting on port {_hostPort}, {result} players, {arg}", Color.green);
		}

		private void DoConnect()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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)
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				SetStatus("NetworkManager not ready.", Color.red);
				return;
			}
			string text = _connectAddress.Trim();
			if (string.IsNullOrEmpty(text))
			{
				SetStatus("Enter an address.", Color.red);
				return;
			}
			if (!string.IsNullOrEmpty(_platformId))
			{
				Plugin.ConfigPlatformId.Value = _platformId;
			}
			SetConVar("cl_password", _clientPassword);
			string text2 = ((text.Contains(":") && !text.StartsWith("[")) ? ("[" + text + "]:" + _connectPort) : ((!text.StartsWith("[")) ? (text + ":" + _connectPort) : (text.Contains("]:") ? text : (text.TrimEnd(']') + "]:" + _connectPort))));
			AddressPortPair val = default(AddressPortPair);
			if (!AddressPortPair.TryParse(text2, ref val) || !((AddressPortPair)(ref val)).isValid)
			{
				SetStatus("Cannot parse: " + text2, Color.red);
				return;
			}
			string item = text + ":" + _connectPort;
			_recentServers.Remove(item);
			_recentServers.Insert(0, item);
			if (_recentServers.Count > 5)
			{
				_recentServers.RemoveAt(5);
			}
			NetworkManagerSystem.singleton.desiredHost = new HostDescription(val);
			SetStatus($"Connecting to {val.address}:{val.port} ...", Color.cyan);
		}

		private void DoDisconnect()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				NetworkManagerSystem.singleton.desiredHost = HostDescription.none;
				if (NetworkServer.active || NetworkClient.active)
				{
					((NetworkManager)NetworkManagerSystem.singleton).StopHost();
				}
				SetStatus("Disconnected.", Color.yellow);
			}
		}

		private void ParseRecent(string entry)
		{
			int num = entry.LastIndexOf(':');
			if (num > 0)
			{
				_connectAddress = entry.Substring(0, num);
				_connectPort = entry.Substring(num + 1);
			}
			_activeTab = 1;
		}

		private void Row(string label, ref string val, float fieldW)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
			val = GUILayout.TextField(val, _sInput, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(fieldW) });
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		private void PasswordRow(string label, ref string val)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
			val = GUILayout.PasswordField(val, '*', _sInput, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		private static void SetConVar(string name, string value)
		{
			try
			{
				Console instance = Console.instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SubmitCmd((NetworkUser)null, name + " \"" + value + "\"", false);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("SetConVar " + name + ": " + ex.Message));
			}
		}

		private void SetStatus(string msg, Color color)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_statusMessage = msg;
			_statusColor = color;
			_statusClearTime = Time.time + 6f;
			Plugin.Log.LogInfo((object)("[UI] " + msg));
		}

		private GUIStyle MakeBtn(Texture2D normal, Texture2D hover, float h)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_009f: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = 15,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			val.normal.background = normal;
			val.normal.textColor = Color.white;
			val.hover.background = hover;
			val.hover.textColor = Color.white;
			val.active.background = normal;
			val.active.textColor = new Color(0.8f, 0.8f, 0.8f);
			val.fixedHeight = h;
			val.margin = new RectOffset(0, 0, 3, 3);
			return val;
		}

		private static Texture2D Tex(Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2);
			Color[] pixels = (Color[])(object)new Color[4] { c, c, c, c };
			val.SetPixels(pixels);
			val.Apply();
			return val;
		}
	}
	public static class Localization
	{
		public const string BUTTON_DIRECT_CONNECT = "DC_BUTTON_DIRECT_CONNECT";

		public const string TITLE = "DC_TITLE";

		public const string HOST_SECTION = "DC_HOST_SECTION";

		public const string JOIN_SECTION = "DC_JOIN_SECTION";

		public const string LABEL_DISPLAY_NAME = "DC_LABEL_DISPLAY_NAME";

		public const string LABEL_MAX_PLAYERS = "DC_LABEL_MAX_PLAYERS";

		public const string LABEL_PASSWORD = "DC_LABEL_PASSWORD";

		public const string LABEL_ADDRESS = "DC_LABEL_ADDRESS";

		public const string LABEL_PORT = "DC_LABEL_PORT";

		public const string PLACEHOLDER_NICKNAME = "DC_PH_NICKNAME";

		public const string PLACEHOLDER_ADDRESS = "DC_PH_ADDRESS";

		public const string PLACEHOLDER_PASSWORD = "DC_PH_PASSWORD";

		public const string IPV_HINT = "DC_IPV_HINT";

		public const string PW_HINT = "DC_PW_HINT";

		public const string BTN_HOST = "DC_BTN_HOST";

		public const string BTN_CONNECT = "DC_BTN_CONNECT";

		public const string BTN_BACK = "DC_BTN_BACK";

		private static readonly Dictionary<string, Dictionary<string, string>> _translations = new Dictionary<string, Dictionary<string, string>>
		{
			["en"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP Direct Connect",
				["DC_TITLE"] = "IP DIRECT CONNECT",
				["DC_HOST_SECTION"] = "HOST A GAME",
				["DC_JOIN_SECTION"] = "JOIN A GAME",
				["DC_LABEL_DISPLAY_NAME"] = "Display Name",
				["DC_LABEL_MAX_PLAYERS"] = "Max Players",
				["DC_LABEL_PASSWORD"] = "Password",
				["DC_LABEL_ADDRESS"] = "Address",
				["DC_LABEL_PORT"] = "Port",
				["DC_PH_NICKNAME"] = "Enter your nickname...",
				["DC_PH_ADDRESS"] = "IP address...",
				["DC_PH_PASSWORD"] = "optional",
				["DC_IPV_HINT"] = "Supports IPv4 and IPv6 — Example: 192.168.1.100 or [::1]",
				["DC_PW_HINT"] = "Leave password empty for no password",
				["DC_BTN_HOST"] = "HOST GAME",
				["DC_BTN_CONNECT"] = "CONNECT",
				["DC_BTN_BACK"] = "BACK"
			},
			["zh-CN"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP 直连",
				["DC_TITLE"] = "IP 直连",
				["DC_HOST_SECTION"] = "创建房间",
				["DC_JOIN_SECTION"] = "加入房间",
				["DC_LABEL_DISPLAY_NAME"] = "显示名称",
				["DC_LABEL_MAX_PLAYERS"] = "最大人数",
				["DC_LABEL_PASSWORD"] = "密码",
				["DC_LABEL_ADDRESS"] = "地址",
				["DC_LABEL_PORT"] = "端口",
				["DC_PH_NICKNAME"] = "输入你的昵称...",
				["DC_PH_ADDRESS"] = "IP 地址...",
				["DC_PH_PASSWORD"] = "可选",
				["DC_IPV_HINT"] = "支持 IPv4 和 IPv6 — 示例: 192.168.1.100 或 [::1]",
				["DC_PW_HINT"] = "留空表示不设密码",
				["DC_BTN_HOST"] = "创建房间",
				["DC_BTN_CONNECT"] = "连接",
				["DC_BTN_BACK"] = "返回"
			},
			["zh-TW"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP 直連",
				["DC_TITLE"] = "IP 直連",
				["DC_HOST_SECTION"] = "建立房間",
				["DC_JOIN_SECTION"] = "加入房間",
				["DC_LABEL_DISPLAY_NAME"] = "顯示名稱",
				["DC_LABEL_MAX_PLAYERS"] = "最大人數",
				["DC_LABEL_PASSWORD"] = "密碼",
				["DC_LABEL_ADDRESS"] = "地址",
				["DC_LABEL_PORT"] = "端口",
				["DC_PH_NICKNAME"] = "輸入你的暱稱...",
				["DC_PH_ADDRESS"] = "IP 地址...",
				["DC_PH_PASSWORD"] = "可選",
				["DC_IPV_HINT"] = "支援 IPv4 和 IPv6 — 範例: 192.168.1.100 或 [::1]",
				["DC_PW_HINT"] = "留空表示不設密碼",
				["DC_BTN_HOST"] = "建立房間",
				["DC_BTN_CONNECT"] = "連線",
				["DC_BTN_BACK"] = "返回"
			},
			["ja"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP直接接続",
				["DC_TITLE"] = "IP直接接続",
				["DC_HOST_SECTION"] = "ゲームをホスト",
				["DC_JOIN_SECTION"] = "ゲームに参加",
				["DC_LABEL_DISPLAY_NAME"] = "表示名",
				["DC_LABEL_MAX_PLAYERS"] = "最大人数",
				["DC_LABEL_PASSWORD"] = "パスワード",
				["DC_LABEL_ADDRESS"] = "アドレス",
				["DC_LABEL_PORT"] = "ポート",
				["DC_PH_NICKNAME"] = "ニックネームを入力...",
				["DC_PH_ADDRESS"] = "IPアドレス...",
				["DC_PH_PASSWORD"] = "任意",
				["DC_IPV_HINT"] = "IPv4とIPv6に対応 — 例: 192.168.1.100 または [::1]",
				["DC_PW_HINT"] = "空欄でパスワードなし",
				["DC_BTN_HOST"] = "ホスト開始",
				["DC_BTN_CONNECT"] = "接続",
				["DC_BTN_BACK"] = "戻る"
			},
			["ko"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP 직접 연결",
				["DC_TITLE"] = "IP 직접 연결",
				["DC_HOST_SECTION"] = "게임 호스트",
				["DC_JOIN_SECTION"] = "게임 참가",
				["DC_LABEL_DISPLAY_NAME"] = "표시 이름",
				["DC_LABEL_MAX_PLAYERS"] = "최대 인원",
				["DC_LABEL_PASSWORD"] = "비밀번호",
				["DC_LABEL_ADDRESS"] = "주소",
				["DC_LABEL_PORT"] = "포트",
				["DC_PH_NICKNAME"] = "닉네임 입력...",
				["DC_PH_ADDRESS"] = "IP 주소...",
				["DC_PH_PASSWORD"] = "선택사항",
				["DC_IPV_HINT"] = "IPv4 및 IPv6 지원 — 예: 192.168.1.100 또는 [::1]",
				["DC_PW_HINT"] = "비워두면 비밀번호 없음",
				["DC_BTN_HOST"] = "호스트 시작",
				["DC_BTN_CONNECT"] = "연결",
				["DC_BTN_BACK"] = "뒤로"
			},
			["ru"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "Прямое подключение",
				["DC_TITLE"] = "ПРЯМОЕ ПОДКЛЮЧЕНИЕ",
				["DC_HOST_SECTION"] = "СОЗДАТЬ ИГРУ",
				["DC_JOIN_SECTION"] = "ПРИСОЕДИНИТЬСЯ",
				["DC_LABEL_DISPLAY_NAME"] = "Имя",
				["DC_LABEL_MAX_PLAYERS"] = "Макс. игроков",
				["DC_LABEL_PASSWORD"] = "Пароль",
				["DC_LABEL_ADDRESS"] = "Адрес",
				["DC_LABEL_PORT"] = "Порт",
				["DC_PH_NICKNAME"] = "Введите никнейм...",
				["DC_PH_ADDRESS"] = "IP адрес...",
				["DC_PH_PASSWORD"] = "необязательно",
				["DC_IPV_HINT"] = "Поддержка IPv4 и IPv6 — Пример: 192.168.1.100 или [::1]",
				["DC_PW_HINT"] = "Оставьте пустым для игры без пароля",
				["DC_BTN_HOST"] = "СОЗДАТЬ",
				["DC_BTN_CONNECT"] = "ПОДКЛЮЧИТЬСЯ",
				["DC_BTN_BACK"] = "НАЗАД"
			},
			["de"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP-Direktverbindung",
				["DC_TITLE"] = "IP-DIREKTVERBINDUNG",
				["DC_HOST_SECTION"] = "SPIEL HOSTEN",
				["DC_JOIN_SECTION"] = "SPIEL BEITRETEN",
				["DC_LABEL_DISPLAY_NAME"] = "Anzeigename",
				["DC_LABEL_MAX_PLAYERS"] = "Max. Spieler",
				["DC_LABEL_PASSWORD"] = "Passwort",
				["DC_LABEL_ADDRESS"] = "Adresse",
				["DC_LABEL_PORT"] = "Port",
				["DC_PH_NICKNAME"] = "Nickname eingeben...",
				["DC_PH_ADDRESS"] = "IP-Adresse...",
				["DC_PH_PASSWORD"] = "optional",
				["DC_IPV_HINT"] = "IPv4 und IPv6 — Beispiel: 192.168.1.100 oder [::1]",
				["DC_PW_HINT"] = "Leer lassen für kein Passwort",
				["DC_BTN_HOST"] = "HOSTEN",
				["DC_BTN_CONNECT"] = "VERBINDEN",
				["DC_BTN_BACK"] = "ZURÜCK"
			},
			["fr"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "Connexion directe IP",
				["DC_TITLE"] = "CONNEXION DIRECTE IP",
				["DC_HOST_SECTION"] = "HÉBERGER",
				["DC_JOIN_SECTION"] = "REJOINDRE",
				["DC_LABEL_DISPLAY_NAME"] = "Pseudo",
				["DC_LABEL_MAX_PLAYERS"] = "Joueurs max",
				["DC_LABEL_PASSWORD"] = "Mot de passe",
				["DC_LABEL_ADDRESS"] = "Adresse",
				["DC_LABEL_PORT"] = "Port",
				["DC_PH_NICKNAME"] = "Entrez votre pseudo...",
				["DC_PH_ADDRESS"] = "Adresse IP...",
				["DC_PH_PASSWORD"] = "facultatif",
				["DC_IPV_HINT"] = "IPv4 et IPv6 — Exemple : 192.168.1.100 ou [::1]",
				["DC_PW_HINT"] = "Laisser vide = pas de mot de passe",
				["DC_BTN_HOST"] = "HÉBERGER",
				["DC_BTN_CONNECT"] = "CONNECTER",
				["DC_BTN_BACK"] = "RETOUR"
			},
			["es"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "Conexión directa IP",
				["DC_TITLE"] = "CONEXIÓN DIRECTA IP",
				["DC_HOST_SECTION"] = "CREAR PARTIDA",
				["DC_JOIN_SECTION"] = "UNIRSE",
				["DC_LABEL_DISPLAY_NAME"] = "Nombre",
				["DC_LABEL_MAX_PLAYERS"] = "Máx. jugadores",
				["DC_LABEL_PASSWORD"] = "Contraseña",
				["DC_LABEL_ADDRESS"] = "Dirección",
				["DC_LABEL_PORT"] = "Puerto",
				["DC_PH_NICKNAME"] = "Introduce tu apodo...",
				["DC_PH_ADDRESS"] = "Dirección IP...",
				["DC_PH_PASSWORD"] = "opcional",
				["DC_IPV_HINT"] = "IPv4 e IPv6 — Ejemplo: 192.168.1.100 o [::1]",
				["DC_PW_HINT"] = "Dejar vacío = sin contraseña",
				["DC_BTN_HOST"] = "CREAR",
				["DC_BTN_CONNECT"] = "CONECTAR",
				["DC_BTN_BACK"] = "VOLVER"
			},
			["pt-BR"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "Conexão direta IP",
				["DC_TITLE"] = "CONEXÃO DIRETA IP",
				["DC_HOST_SECTION"] = "HOSPEDAR JOGO",
				["DC_JOIN_SECTION"] = "ENTRAR EM JOGO",
				["DC_LABEL_DISPLAY_NAME"] = "Nome",
				["DC_LABEL_MAX_PLAYERS"] = "Máx. jogadores",
				["DC_LABEL_PASSWORD"] = "Senha",
				["DC_LABEL_ADDRESS"] = "Endereço",
				["DC_LABEL_PORT"] = "Porta",
				["DC_PH_NICKNAME"] = "Digite seu apelido...",
				["DC_PH_ADDRESS"] = "Endereço IP...",
				["DC_PH_PASSWORD"] = "opcional",
				["DC_IPV_HINT"] = "IPv4 e IPv6 — Exemplo: 192.168.1.100 ou [::1]",
				["DC_PW_HINT"] = "Deixe vazio para sem senha",
				["DC_BTN_HOST"] = "HOSPEDAR",
				["DC_BTN_CONNECT"] = "CONECTAR",
				["DC_BTN_BACK"] = "VOLTAR"
			},
			["tr"] = new Dictionary<string, string>
			{
				["DC_BUTTON_DIRECT_CONNECT"] = "IP Doğrudan Bağlantı",
				["DC_TITLE"] = "IP DOĞRUDAN BAĞLANTI",
				["DC_HOST_SECTION"] = "OYUN OLUŞTUR",
				["DC_JOIN_SECTION"] = "OYUNA KATIL",
				["DC_LABEL_DISPLAY_NAME"] = "Görünen Ad",
				["DC_LABEL_MAX_PLAYERS"] = "Maks. Oyuncu",
				["DC_LABEL_PASSWORD"] = "Şifre",
				["DC_LABEL_ADDRESS"] = "Adres",
				["DC_LABEL_PORT"] = "Port",
				["DC_PH_NICKNAME"] = "Takma adınızı girin...",
				["DC_PH_ADDRESS"] = "IP adresi...",
				["DC_PH_PASSWORD"] = "isteğe bağlı",
				["DC_IPV_HINT"] = "IPv4 ve IPv6 — Örnek: 192.168.1.100 veya [::1]",
				["DC_PW_HINT"] = "Boş bırakırsanız şifre yok",
				["DC_BTN_HOST"] = "OLUŞTUR",
				["DC_BTN_CONNECT"] = "BAĞLAN",
				["DC_BTN_BACK"] = "GERİ"
			}
		};

		public static void RegisterAll()
		{
			foreach (KeyValuePair<string, Dictionary<string, string>> translation in _translations)
			{
				Language val = Language.FindLanguageByName(translation.Key);
				if (val == null)
				{
					continue;
				}
				foreach (KeyValuePair<string, string> item in translation.Value)
				{
					val.SetStringByToken(item.Key, item.Value);
				}
			}
			Language currentLanguage = Language.currentLanguage;
			if (currentLanguage != null && !_translations.ContainsKey(currentLanguage.name))
			{
				foreach (KeyValuePair<string, string> item2 in _translations["en"])
				{
					currentLanguage.SetStringByToken(item2.Key, item2.Value);
				}
			}
			Plugin.Log.LogInfo((object)$"Localization registered for {_translations.Count} languages.");
		}

		public static string Get(string token)
		{
			return Language.GetString(token);
		}
	}
	[BepInPlugin("com.ror2.directconnect", "RoR2DirectConnect", "2.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.ror2.directconnect";

		public const string PluginName = "RoR2DirectConnect";

		public const string PluginVersion = "2.0.2";

		public static ConfigEntry<string> ConfigPlatformId;

		public static ConfigEntry<string> ConfigDisplayName;

		public static ConfigEntry<bool> ConfigBypassSteamAuth;

		public static ConfigEntry<bool> ConfigBypassLobbyCheck;

		public static ConfigEntry<string> ConfigLastAddress;

		public static ConfigEntry<string> ConfigLastPort;

		public static ConfigEntry<string> ConfigLastMaxPlayers;

		public static ConfigEntry<string> ConfigLastHostPassword;

		public static ConfigEntry<string> ConfigLastClientPassword;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static bool DirectConnectActive { get; set; }

		private void Awake()
		{
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigPlatformId = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PlatformId", "76561198000000000", "Custom Platform ID for direct connect. Each player must use a unique ID.");
			ConfigDisplayName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DisplayName", "", "Your in-game display name for direct connect. If empty, falls back to profile name.");
			ConfigBypassSteamAuth = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BypassSteamAuth", true, "Bypass Steam authentication. Required for LAN/tunneling play.");
			ConfigBypassLobbyCheck = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BypassLobbyCheck", true, "Bypass Steam lobby check when hosting. Required for direct IP hosting.");
			ConfigLastAddress = ((BaseUnityPlugin)this).Config.Bind<string>("SavedUI", "LastAddress", "", "Last used server address.");
			ConfigLastPort = ((BaseUnityPlugin)this).Config.Bind<string>("SavedUI", "LastPort", "7777", "Last used port.");
			ConfigLastMaxPlayers = ((BaseUnityPlugin)this).Config.Bind<string>("SavedUI", "LastMaxPlayers", "4", "Last used max players.");
			ConfigLastHostPassword = ((BaseUnityPlugin)this).Config.Bind<string>("SavedUI", "LastHostPassword", "", "Last used host password.");
			ConfigLastClientPassword = ((BaseUnityPlugin)this).Config.Bind<string>("SavedUI", "LastClientPassword", "", "Last used client password.");
			_harmony = new Harmony("com.ror2.directconnect");
			_harmony.PatchAll(typeof(AddressPortPairPatch));
			_harmony.PatchAll(typeof(PlatformAuthPatch));
			_harmony.PatchAll(typeof(AddPlayerIdFromPlatformPatch));
			_harmony.PatchAll(typeof(PlatformHostPatch));
			_harmony.PatchAll(typeof(UpdateServerPatch));
			_harmony.PatchAll(typeof(InitPlatformServerPatch));
			_harmony.PatchAll(typeof(InitP2PPatch));
			SteamServerPatches.Apply(_harmony);
			_harmony.PatchAll(typeof(CreateLobbyPatch));
			_harmony.PatchAll(typeof(JoinLobbyPatch));
			_harmony.PatchAll(typeof(OnLobbyJoinedPatch));
			_harmony.PatchAll(typeof(IsInLobbyPatch));
			_harmony.PatchAll(typeof(OwnsLobbyPatch));
			_harmony.PatchAll(typeof(SteamLobbyOnStopClientPatch));
			_harmony.PatchAll(typeof(EnsureDesiredHostPatch));
			_harmony.PatchAll(typeof(SteamLobbyFinderUpdatePatch));
			_harmony.PatchAll(typeof(ResetOnStopClient));
			_harmony.PatchAll(typeof(ResetOnStopHost));
			_harmony.PatchAll(typeof(DisplayNamePatch));
			_harmony.PatchAll(typeof(ResolveNamePatch));
			Language.onCurrentLanguageChanged += Localization.RegisterAll;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Localization.RegisterAll));
			_harmony.PatchAll(typeof(MenuInjector));
			_harmony.PatchAll(typeof(DirectConnectCommands));
			((Component)this).gameObject.AddComponent<DirectConnectUI>();
			Log.LogInfo((object)"RoR2DirectConnect v2.0 loaded! Native UI injected into Multiplayer menu.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace RoR2DirectConnect.UI
{
	public class DirectConnectPanel : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <WaitForConnectionOrRestore>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AddressPortPair pair;

			public DirectConnectPanel <>4__this;

			private float <t>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_015d: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				DirectConnectPanel directConnectPanel = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__2 < 10f)
				{
					if (NetworkClient.active && NetworkClient.allClients.Count > 0)
					{
						NetworkClient val = NetworkClient.allClients[0];
						if (val != null && val.isConnected)
						{
							Plugin.Log.LogInfo((object)$"Connected to {pair.address}:{pair.port}");
							return false;
						}
					}
					if (!((Object)(object)NetworkManagerSystem.singleton != (Object)null) || (int)NetworkManagerSystem.singleton.desiredHost.hostType != 0)
					{
						<t>5__2 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
				}
				Plugin.Log.LogError((object)$"Connection to {pair.address}:{pair.port} failed (timeout 10s).");
				Plugin.DirectConnectActive = false;
				CreateLobbyPatch.CleanupFakeLobbyState();
				if ((Object)(object)directConnectPanel.menuController != (Object)null)
				{
					MenuInjector.ShowPanel(directConnectPanel.menuController);
				}
				directConnectPanel.SetStatus($"Connection failed: {pair.address}:{pair.port}", Color.red);
				return false;
			}

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

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

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

			private object <>2__current;

			public DirectConnectPanel <>4__this;

			private float <t>5__2;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				DirectConnectPanel directConnectPanel = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!NetworkServer.active && <t>5__2 < 5f)
				{
					<t>5__2 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (!NetworkServer.active)
				{
					Plugin.Log.LogError((object)"Server failed to start within 5s.");
					Plugin.DirectConnectActive = false;
					if ((Object)(object)directConnectPanel.menuController != (Object)null)
					{
						MenuInjector.ShowPanel(directConnectPanel.menuController);
					}
				}
				else
				{
					Plugin.Log.LogInfo((object)"Server started successfully.");
				}
				return false;
			}

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

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

		public MultiplayerMenuController menuController;

		private TMP_InputField _hostNicknameInput;

		private TMP_InputField _hostMaxPlayersInput;

		private TMP_InputField _hostPasswordInput;

		private TMP_InputField _joinNicknameInput;

		private TMP_InputField _joinAddressInput;

		private TMP_InputField _joinPortInput;

		private TMP_InputField _joinPasswordInput;

		private TextMeshProUGUI _statusLabel;

		private const float PANEL_WIDTH = 620f;

		private void OnEnable()
		{
			for (int num = ((Component)this).transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)((Component)this).transform.GetChild(num)).gameObject);
			}
			BuildPanel();
		}

		private void BuildPanel()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Expected O, but got Unknown
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Expected O, but got Unknown
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)this).GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
			}
			GameObject val = new GameObject("Center", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0f);
			component2.anchorMax = new Vector2(0.5f, 1f);
			component2.sizeDelta = new Vector2(620f, 0f);
			component2.anchoredPosition = Vector2.zero;
			GameObject val2 = new GameObject("BG", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(val.transform, false);
			StretchRT(val2);
			Image component3 = val2.GetComponent<Image>();
			((Graphic)component3).color = new Color(0.06f, 0.06f, 0.09f, 0.82f);
			((Graphic)component3).raycastTarget = false;
			GameObject val3 = new GameObject("Content", new Type[2]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup)
			});
			val3.transform.SetParent(val.transform, false);
			StretchRT(val3);
			VerticalLayoutGroup component4 = val3.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component4).spacing = 6f;
			((LayoutGroup)component4).padding = new RectOffset(35, 35, 25, 20);
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true;
			((LayoutGroup)component4).childAlignment = (TextAnchor)1;
			Transform transform = val3.transform;
			AddLabel(transform, L("DC_TITLE"), 26f, (FontStyles)1, (TextAlignmentOptions)514, Color.white, 42f);
			AddDivider(transform);
			AddSpacer(transform, 4f);
			AddLabel(transform, L("DC_HOST_SECTION"), 16f, (FontStyles)1, (TextAlignmentOptions)513, new Color(0.55f, 0.78f, 1f), 26f);
			AddLabel(transform, L("DC_LABEL_DISPLAY_NAME"), 13f, (FontStyles)0, (TextAlignmentOptions)513, new Color(0.9f, 0.9f, 0.95f), 20f);
			_hostNicknameInput = AddInputField(transform, L("DC_PH_NICKNAME"), Plugin.ConfigDisplayName.Value);
			AddSpacer(transform, 4f);
			Transform parent = AddRow(transform);
			AddLabel(parent, L("DC_LABEL_MAX_PLAYERS"), 13f, (FontStyles)0, (TextAlignmentOptions)4100, new Color(0.9f, 0.9f, 0.95f), 32f, 90f);
			_hostMaxPlayersInput = AddInputField(parent, "4", Plugin.ConfigLastMaxPlayers.Value, isPassword: false, 50f);
			AddLabel(parent, L("DC_LABEL_PASSWORD"), 13f, (FontStyles)0, (TextAlignmentOptions)4100, new Color(0.9f, 0.9f, 0.95f), 32f, 70f);
			_hostPasswordInput = AddInputField(parent, L("DC_PH_PASSWORD"), Plugin.ConfigLastHostPassword.Value, isPassword: true);
			AddSpacer(transform, 4f);
			CloneBtn(transform, L("DC_BTN_HOST"), new UnityAction(DoHost));
			AddSpacer(transform, 8f);
			AddDivider(transform);
			AddSpacer(transform, 8f);
			AddLabel(transform, L("DC_JOIN_SECTION"), 16f, (FontStyles)1, (TextAlignmentOptions)513, new Color(0.55f, 0.78f, 1f), 26f);
			AddLabel(transform, L("DC_LABEL_DISPLAY_NAME"), 13f, (FontStyles)0, (TextAlignmentOptions)513, new Color(0.9f, 0.9f, 0.95f), 20f);
			_joinNicknameInput = AddInputField(transform, L("DC_PH_NICKNAME"), Plugin.ConfigDisplayName.Value);
			AddSpacer(transform, 4f);
			AddLabel(transform, L("DC_IPV_HINT"), 11f, (FontStyles)2, (TextAlignmentOptions)513, new Color(0.7f, 0.7f, 0.75f), 16f);
			Transform parent2 = AddRow(transform);
			AddLabel(parent2, L("DC_LABEL_ADDRESS"), 13f, (FontStyles)0, (TextAlignmentOptions)4100, new Color(0.9f, 0.9f, 0.95f), 32f, 60f);
			_joinAddressInput = AddInputField(parent2, L("DC_PH_ADDRESS"), Plugin.ConfigLastAddress.Value);
			AddLabel(parent2, ":", 13f, (FontStyles)0, (TextAlignmentOptions)514, new Color(0.9f, 0.9f, 0.95f), 32f, 10f);
			_joinPortInput = AddInputField(parent2, "7777", Plugin.ConfigLastPort.Value, isPassword: false, 70f);
			Transform parent3 = AddRow(transform);
			AddLabel(parent3, L("DC_LABEL_PASSWORD"), 13f, (FontStyles)0, (TextAlignmentOptions)4100, new Color(0.9f, 0.9f, 0.95f), 32f, 60f);
			_joinPasswordInput = AddInputField(parent3, L("DC_PH_PASSWORD"), Plugin.ConfigLastClientPassword.Value, isPassword: true);
			AddSpacer(transform, 4f);
			CloneBtn(transform, L("DC_BTN_CONNECT"), new UnityAction(DoConnect));
			AddSpacer(transform, 8f);
			AddDivider(transform);
			AddSpacer(transform, 6f);
			CloneBtn(transform, L("DC_BTN_BACK"), (UnityAction)delegate
			{
				MenuInjector.HidePanel(menuController);
			});
			AddSpacer(transform, 6f);
			_statusLabel = AddLabel(transform, "", 14f, (FontStyles)1, (TextAlignmentOptions)514, new Color(0.5f, 0.9f, 0.6f), 22f);
			GameObject val4 = new GameObject("BottomSpacer", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val4.transform.SetParent(transform, false);
			val4.GetComponent<LayoutElement>().flexibleHeight = 1f;
		}

		private void DoHost()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				SetStatus("NetworkManager not ready.", Color.red);
				return;
			}
			Plugin.DirectConnectActive = true;
			SaveNickname(_hostNicknameInput);
			TMP_InputField hostPasswordInput = _hostPasswordInput;
			SetConVar("sv_password", ((hostPasswordInput != null) ? hostPasswordInput.text : null) ?? "");
			int num = 4;
			if ((Object)(object)_hostMaxPlayersInput != (Object)null && int.TryParse(_hostMaxPlayersInput.text, out var result) && result > 0 && result <= 16)
			{
				num = result;
			}
			SetConVar("sv_maxplayers", num.ToString());
			Plugin.ConfigLastMaxPlayers.Value = num.ToString();
			ConfigEntry<string> configLastHostPassword = Plugin.ConfigLastHostPassword;
			TMP_InputField hostPasswordInput2 = _hostPasswordInput;
			configLastHostPassword.Value = ((hostPasswordInput2 != null) ? hostPasswordInput2.text : null) ?? "";
			CreateLobbyPatch.FakeLobbyState();
			NetworkManagerSystem.singleton.desiredHost = new HostDescription(new HostingParameters
			{
				listen = true,
				maxPlayers = num
			});
			Plugin.Log.LogInfo((object)$"Direct connect host: {num} players");
			MenuInjector.DismissPanel(menuController);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(WaitForServerOrRestore());
		}

		[IteratorStateMachine(typeof(<WaitForServerOrRestore>d__13))]
		private IEnumerator WaitForServerOrRestore()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForServerOrRestore>d__13(0)
			{
				<>4__this = this
			};
		}

		private void DoConnect()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				SetStatus("NetworkManager not ready.", Color.red);
				EnsurePanelVisible();
				return;
			}
			TMP_InputField joinAddressInput = _joinAddressInput;
			string text = ((joinAddressInput == null) ? null : joinAddressInput.text?.Trim()) ?? "";
			if (string.IsNullOrEmpty(text))
			{
				SetStatus("Enter an address!", Color.red);
				EnsurePanelVisible();
				return;
			}
			Plugin.DirectConnectActive = true;
			SaveNickname(_joinNicknameInput);
			TMP_InputField joinPasswordInput = _joinPasswordInput;
			SetConVar("cl_password", ((joinPasswordInput != null) ? joinPasswordInput.text : null) ?? "");
			Plugin.ConfigLastAddress.Value = text;
			ConfigEntry<string> configLastPort = Plugin.ConfigLastPort;
			TMP_InputField joinPortInput = _joinPortInput;
			configLastPort.Value = ((joinPortInput != null) ? joinPortInput.text : null) ?? "7777";
			ConfigEntry<string> configLastClientPassword = Plugin.ConfigLastClientPassword;
			TMP_InputField joinPasswordInput2 = _joinPasswordInput;
			configLastClientPassword.Value = ((joinPasswordInput2 != null) ? joinPasswordInput2.text : null) ?? "";
			CreateLobbyPatch.FakeLobbyState();
			TMP_InputField joinPortInput2 = _joinPortInput;
			string text2 = ((joinPortInput2 != null) ? joinPortInput2.text : null) ?? "7777";
			string text3 = ((text.Contains(":") && !text.StartsWith("[")) ? ("[" + text + "]:" + text2) : ((!text.StartsWith("[")) ? (text + ":" + text2) : (text.Contains("]:") ? text : (text.TrimEnd(']') + "]:" + text2))));
			AddressPortPair val = default(AddressPortPair);
			if (!AddressPortPair.TryParse(text3, ref val) || !((AddressPortPair)(ref val)).isValid)
			{
				SetStatus("Invalid address: " + text3, Color.red);
				Plugin.DirectConnectActive = false;
				EnsurePanelVisible();
			}
			else
			{
				NetworkManagerSystem.singleton.desiredHost = new HostDescription(val);
				Plugin.Log.LogInfo((object)$"Connecting to {val.address}:{val.port}...");
				MenuInjector.DismissPanel(menuController);
				((MonoBehaviour)Plugin.Instance).StartCoroutine(WaitForConnectionOrRestore(val));
			}
		}

		[IteratorStateMachine(typeof(<WaitForConnectionOrRestore>d__15))]
		private IEnumerator WaitForConnectionOrRestore(AddressPortPair pair)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForConnectionOrRestore>d__15(0)
			{
				<>4__this = this,
				pair = pair
			};
		}

		private void SaveNickname(TMP_InputField nicknameInput)
		{
			string text = ((nicknameInput != null) ? nicknameInput.text : null) ?? "";
			if (!string.IsNullOrEmpty(text))
			{
				Plugin.ConfigDisplayName.Value = text;
				ulong num = (ulong)((text.GetHashCode() & 0x7FFFFFFF) + 76561198000000000L);
				Plugin.ConfigPlatformId.Value = num.ToString();
			}
		}

		private void SetStatus(string msg, Color c)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_statusLabel != (Object)null)
			{
				((TMP_Text)_statusLabel).text = msg;
				((Graphic)_statusLabel).color = c;
			}
			Plugin.Log.LogInfo((object)("[Panel] " + msg));
		}

		private void EnsurePanelVisible()
		{
			if ((Object)(object)menuController != (Object)null)
			{
				MenuInjector.ShowPanel(menuController);
			}
		}

		private static void SetConVar(string n, string v)
		{
			try
			{
				Console instance = Console.instance;
				if (instance != null)
				{
					instance.SubmitCmd((NetworkUser)null, n + " \"" + v + "\"", false);
				}
			}
			catch
			{
			}
		}

		private static string L(string token)
		{
			return Localization.Get(token);
		}

		private static TextMeshProUGUI AddLabel(Transform parent, string text, float size, FontStyles style, TextAlignmentOptions align, Color color, float height, float fixedW = -1f)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Lbl", new Type[3]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = text;
			((TMP_Text)component).fontSize = size;
			((TMP_Text)component).fontStyle = style;
			((TMP_Text)component).alignment = align;
			((Graphic)component).color = color;
			((TMP_Text)component).overflowMode = (TextOverflowModes)0;
			((TMP_Text)component).enableWordWrapping = false;
			((Graphic)component).raycastTarget = false;
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			component2.preferredHeight = height;
			if (fixedW > 0f)
			{
				component2.preferredWidth = fixedW;
				component2.minWidth = fixedW;
			}
			else
			{
				component2.flexibleWidth = 1f;
			}
			return component;
		}

		private static TMP_InputField AddInputField(Transform parent, string placeholder, string defaultVal, bool isPassword = false, float fixedW = -1f)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_012f: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Input", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(LayoutElement),
				typeof(MPEventSystemLocator)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.16f, 0.16f, 0.22f, 0.95f);
			((Graphic)component).raycastTarget = true;
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			component2.preferredHeight = 34f;
			component2.minHeight = 34f;
			component2.flexibleHeight = 0f;
			if (fixedW > 0f)
			{
				component2.preferredWidth = fixedW;
				component2.minWidth = fixedW;
			}
			else
			{
				component2.flexibleWidth = 1f;
			}
			Outline obj = val.AddComponent<Outline>();
			((Shadow)obj).effectColor = new Color(0.35f, 0.4f, 0.55f, 0.6f);
			((Shadow)obj).effectDistance = new Vector2(1f, -1f);
			GameObject val2 = new GameObject("VP", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = new Vector2(8f, 2f);
			component3.offsetMax = new Vector2(-8f, -2f);
			GameObject val3 = new GameObject("PH", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val3.transform.SetParent(val2.transform, false);
			StretchRT(val3);
			TextMeshProUGUI component4 = val3.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component4).text = placeholder;
			((TMP_Text)component4).fontSize = 14f;
			((TMP_Text)component4).fontStyle = (FontStyles)2;
			((Graphic)component4).color = new Color(0.55f, 0.55f, 0.62f);
			((TMP_Text)component4).alignment = (TextAlignmentOptions)4097;
			((Graphic)component4).raycastTarget = false;
			GameObject val4 = new GameObject("TX", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val4.transform.SetParent(val2.transform, false);
			StretchRT(val4);
			TextMeshProUGUI component5 = val4.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component5).fontSize = 14f;
			((Graphic)component5).color = Color.white;
			((TMP_Text)component5).alignment = (TextAlignmentOptions)4097;
			((Graphic)component5).raycastTarget = false;
			GameObject val5 = new GameObject("Caret", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(LayoutElement)
			});
			val5.transform.SetParent(val2.transform, false);
			StretchRT(val5);
			val5.GetComponent<LayoutElement>().ignoreLayout = true;
			TMP_InputField val6 = val.AddComponent<TMP_InputField>();
			val6.textViewport = component3;
			val6.textComponent = (TMP_Text)(object)component5;
			val6.placeholder = (Graphic)(object)component4;
			val6.text = defaultVal;
			val6.pointSize = 14f;
			val6.customCaretColor = true;
			val6.caretColor = Color.white;
			val6.caretWidth = 2;
			val6.caretBlinkRate = 0.85f;
			val6.selectionColor = new Color(0.3f, 0.5f, 0.8f, 0.4f);
			val6.onFocusSelectAll = false;
			val6.richText = false;
			val6.restoreOriginalTextOnEscape = true;
			if (isPassword)
			{
				val6.contentType = (ContentType)7;
				val6.asteriskChar = '*';
			}
			return val6;
		}

		private static Transform AddRow(Transform parent, int spacing = 8, float height = 34f)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row", new Type[3]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			HorizontalLayoutGroup component = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).spacing = spacing;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = false;
			((LayoutGroup)component).childAlignment = (TextAnchor)3;
			val.GetComponent<LayoutElement>().preferredHeight = height;
			return val.transform;
		}

		private static void CloneBtn(Transform parent, string text, UnityAction onClick)
		{
			MPButton val = MenuInjector.CloneButton(parent, text, onClick);
			if (!((Object)(object)val == (Object)null))
			{
				LayoutElement val2 = ((Component)val).GetComponent<LayoutElement>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).gameObject.AddComponent<LayoutElement>();
				}
				val2.flexibleWidth = 1f;
				val2.flexibleHeight = 0f;
				val2.preferredHeight = 45f;
				val2.minHeight = 45f;
				val2.minWidth = 100f;
			}
		}

		private static void AddSpacer(Transform parent, float h)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Spacer", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			val.GetComponent<LayoutElement>().preferredHeight = h;
		}

		private static void AddDivider(Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Div", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.35f, 0.4f, 0.5f, 0.6f);
			((Graphic)component).raycastTarget = false;
			val.GetComponent<LayoutElement>().preferredHeight = 1f;
		}

		private static void StretchRT(GameObject go)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = go.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
			}
		}
	}
	[HarmonyPatch]
	public static class MenuInjector
	{
		private static GameObject _directConnectMenu;

		private static GameObject _directConnectButton;

		public static GameObject ButtonTemplate { get; private set; }

		[HarmonyPatch(typeof(MultiplayerMenuController), "OnEnable")]
		[HarmonyPostfix]
		private static void OnEnablePostfix(MultiplayerMenuController __instance)
		{
			try
			{
				Inject(__instance);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"MenuInjector: {arg}");
			}
		}

		[HarmonyPatch(typeof(MultiplayerMenuController), "SetSubview")]
		[HarmonyPostfix]
		private static void SetSubviewPostfix()
		{
			if ((Object)(object)_directConnectMenu != (Object)null)
			{
				_directConnectMenu.SetActive(false);
			}
		}

		private static void Inject(MultiplayerMenuController ctrl)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			MPButton hostGame = ctrl.hostGame;
			GameObject val = ((hostGame != null) ? ((Component)hostGame).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ButtonTemplate = val;
			if ((Object)(object)_directConnectButton == (Object)null || !Object.op_Implicit((Object)(object)_directConnectButton))
			{
				_directConnectButton = Object.Instantiate<GameObject>(val, val.transform.parent);
				((Object)_directConnectButton).name = "DirectConnectButton";
				_directConnectButton.transform.SetSiblingIndex(val.transform.GetSiblingIndex() + 1);
				LanguageTextMeshController[] componentsInChildren = _directConnectButton.GetComponentsInChildren<LanguageTextMeshController>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
				}
				TextMeshProUGUI[] componentsInChildren2 = _directConnectButton.GetComponentsInChildren<TextMeshProUGUI>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((TMP_Text)componentsInChildren2[i]).text = Localization.Get("DC_BUTTON_DIRECT_CONNECT");
				}
			}
			HGButton component = _directConnectButton.GetComponent<HGButton>();
			if ((Object)(object)component != (Object)null)
			{
				component.hoverLanguageTextMeshController = null;
				((UnityEventBase)((Button)component).onClick).RemoveAllListeners();
				((UnityEvent)((Button)component).onClick).AddListener((UnityAction)delegate
				{
					ShowPanel(ctrl);
				});
			}
			if ((Object)(object)_directConnectMenu == (Object)null || !Object.op_Implicit((Object)(object)_directConnectMenu))
			{
				GameObject hostGameMenu = ctrl.HostGameMenu;
				if ((Object)(object)hostGameMenu == (Object)null)
				{
					return;
				}
				_directConnectMenu = Object.Instantiate<GameObject>(hostGameMenu, hostGameMenu.transform.parent);
				((Object)_directConnectMenu).name = "DirectConnectMenu";
				_directConnectMenu.SetActive(false);
				HostGamePanelController component2 = _directConnectMenu.GetComponent<HostGamePanelController>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component2);
				}
				for (int num = _directConnectMenu.transform.childCount - 1; num >= 0; num--)
				{
					Object.DestroyImmediate((Object)(object)((Component)_directConnectMenu.transform.GetChild(num)).gameObject);
				}
				_directConnectMenu.AddComponent<DirectConnectPanel>();
				Plugin.Log.LogInfo((object)"Injected 'IP Direct Connect' button + panel.");
			}
			DirectConnectPanel component3 = _directConnectMenu.GetComponent<DirectConnectPanel>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.menuController = ctrl;
			}
		}

		public static void ShowPanel(MultiplayerMenuController ctrl)
		{
			if ((Object)(object)_directConnectMenu == (Object)null || !Object.op_Implicit((Object)(object)_directConnectMenu))
			{
				Plugin.Log.LogWarning((object)"DirectConnect panel missing — recreating...");
				try
				{
					Inject(ctrl);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Panel recreation failed: {arg}");
				}
			}
			if ((Object)(object)_directConnectMenu == (Object)null || !Object.op_Implicit((Object)(object)_directConnectMenu))
			{
				Plugin.Log.LogError((object)"Cannot show DirectConnect panel.");
				return;
			}
			ctrl.MainMultiplayerMenu.SetActive(false);
			ctrl.HostGameMenu.SetActive(false);
			ctrl.JoinGameMenu.SetActive(false);
			_directConnectMenu.SetActive(true);
		}

		public static void HidePanel(MultiplayerMenuController ctrl)
		{
			if ((Object)(object)_directConnectMenu != (Object)null)
			{
				_directConnectMenu.SetActive(false);
			}
			Plugin.DirectConnectActive = false;
			ctrl.SetSubview((Subview)0);
		}

		public static void DismissPanel(MultiplayerMenuController ctrl)
		{
			if ((Object)(object)_directConnectMenu != (Object)null)
			{
				_directConnectMenu.SetActive(false);
			}
		}

		public static MPButton CloneButton(Transform parent, string text, UnityAction onClick)
		{
			if ((Object)(object)ButtonTemplate == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(ButtonTemplate, parent);
			((Object)val).name = "Btn_" + text.Replace(" ", "");
			LanguageTextMeshController[] componentsInChildren = val.GetComponentsInChildren<LanguageTextMeshController>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			TextMeshProUGUI[] componentsInChildren2 = val.GetComponentsInChildren<TextMeshProUGUI>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((TMP_Text)componentsInChildren2[i]).text = text;
			}
			HGButton component = val.GetComponent<HGButton>();
			if ((Object)(object)component != (Object)null)
			{
				component.hoverLanguageTextMeshController = null;
			}
			MPButton component2 = val.GetComponent<MPButton>();
			if ((Object)(object)component2 != (Object)null)
			{
				((UnityEventBase)((Button)component2).onClick).RemoveAllListeners();
				((UnityEvent)((Button)component2).onClick).AddListener(onClick);
			}
			val.SetActive(true);
			return component2;
		}
	}
}
namespace RoR2DirectConnect.Patches
{
	[HarmonyPatch(typeof(AddressPortPair), "TryParse")]
	public static class AddressPortPairPatch
	{
		private static bool Prefix(string str, out AddressPortPair addressPortPair, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			addressPortPair = default(AddressPortPair);
			if (string.IsNullOrEmpty(str))
			{
				__result = false;
				return false;
			}
			if (str.StartsWith("["))
			{
				int num = str.IndexOf(']');
				if (num < 0)
				{
					__result = false;
					return false;
				}
				string text = str.Substring(1, num - 1);
				ushort result = 7777;
				if (num + 1 < str.Length && str[num + 1] == ':' && !ushort.TryParse(str.Substring(num + 2), out result))
				{
					result = 7777;
				}
				addressPortPair.address = text;
				addressPortPair.port = result;
				__result = true;
				Plugin.Log.LogInfo((object)$"Parsed IPv6 address: [{text}]:{result}");
				return false;
			}
			int num2 = 0;
			for (int i = 0; i < str.Length; i++)
			{
				if (str[i] == ':')
				{
					num2++;
				}
			}
			if (num2 > 1)
			{
				addressPortPair.address = str;
				addressPortPair.port = 7777;
				__result = true;
				Plugin.Log.LogInfo((object)("Parsed bare IPv6 address: " + str + ":7777 (default port)"));
				return false;
			}
			return true;
		}
	}
	public static class DirectConnectCommands
	{
		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCDirectConnect(ConCommandArgs args)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			string argString = ((ConCommandArgs)(ref args)).GetArgString(0);
			AddressPortPair val = default(AddressPortPair);
			if (string.IsNullOrEmpty(argString))
			{
				Debug.Log((object)"[DirectConnect] Usage: dc_connect ip:port  OR  dc_connect [::1]:7777");
			}
			else if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				Debug.Log((object)"[DirectConnect] NetworkManager not ready.");
			}
			else if (!AddressPortPair.TryParse(argString, ref val) || !((AddressPortPair)(ref val)).isValid)
			{
				Debug.Log((object)("[DirectConnect] Failed to parse address: " + argString));
				Debug.Log((object)"[DirectConnect] IPv4 format: 192.168.1.1:7777");
				Debug.Log((object)"[DirectConnect] IPv6 format: [::1]:7777 or [2001:db8::1]:7777");
			}
			else
			{
				Plugin.DirectConnectActive = true;
				AccessTools.Method(typeof(NetworkManagerSystem), "EnsureNetworkManagerNotBusy", (Type[])null, (Type[])null).Invoke(null, null);
				NetworkManagerSystem.singleton.desiredHost = new HostDescription(val);
				Debug.Log((object)$"[DirectConnect] Connecting to {val.address}:{val.port} ...");
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCDirectHost(ConCommandArgs args)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				Debug.Log((object)"[DirectConnect] NetworkManager not ready.");
				return;
			}
			if (NetworkServer.active)
			{
				Debug.Log((object)"[DirectConnect] Server is already running.");
				return;
			}
			int num = 4;
			if (((ConCommandArgs)(ref args)).Count > 0)
			{
				int argInt = ((ConCommandArgs)(ref args)).GetArgInt(0);
				if (argInt > 0 && argInt <= 16)
				{
					num = argInt;
				}
			}
			Plugin.DirectConnectActive = true;
			NetworkManagerSystem.singleton.desiredHost = new HostDescription(new HostingParameters
			{
				listen = true,
				maxPlayers = num
			});
			Debug.Log((object)($"[DirectConnect] Hosting with maxPlayers={num}. " + "Clients can connect with: dc_connect YOUR_IP:7777"));
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCDirectId(ConCommandArgs args)
		{
			if (((ConCommandArgs)(ref args)).Count > 0)
			{
				string argString = ((ConCommandArgs)(ref args)).GetArgString(0);
				if (ulong.TryParse(argString, out var _))
				{
					Plugin.ConfigPlatformId.Value = argString;
					Debug.Log((object)("[DirectConnect] PlatformID set to: " + argString));
				}
				else
				{
					Debug.Log((object)"[DirectConnect] Invalid ID. Must be a number. Example: 76561198012345678");
				}
			}
			else
			{
				Debug.Log((object)("[DirectConnect] Current PlatformID: " + Plugin.ConfigPlatformId.Value));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCDirectStatus(ConCommandArgs args)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)"=== DirectConnect Status ===");
			Debug.Log((object)("  PlatformID:        " + Plugin.ConfigPlatformId.Value));
			Debug.Log((object)$"  BypassSteamAuth:   {Plugin.ConfigBypassSteamAuth.Value}");
			Debug.Log((object)$"  BypassLobbyCheck:  {Plugin.ConfigBypassLobbyCheck.Value}");
			Debug.Log((object)$"  Server active:     {NetworkServer.active}");
			Debug.Log((object)$"  Client active:     {NetworkClient.active}");
			if (Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				HostDescription desiredHost = NetworkManagerSystem.singleton.desiredHost;
				Debug.Log((object)$"  DesiredHost type:  {desiredHost.hostType}");
				if ((int)desiredHost.hostType == 3)
				{
					Debug.Log((object)$"  Target address:    {desiredHost.addressPortPair.address}:{desiredHost.addressPortPair.port}");
				}
			}
			if (NetworkServer.active)
			{
				Debug.Log((object)$"  Connections:       {NetworkServer.connections.Count}");
				Debug.Log((object)$"  Listen port:       {((NetworkManager)NetworkManagerSystem.singleton).networkPort}");
			}
			Debug.Log((object)"============================");
		}
	}
	[HarmonyPatch(typeof(NetworkUser), "GetNetworkPlayerName")]
	public static class DisplayNamePatch
	{
		private static void Postfix(NetworkUser __instance, ref NetworkPlayerName __result)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DirectConnectActive)
			{
				return;
			}
			if (((NetworkBehaviour)__instance).isLocalPlayer)
			{
				string value = Plugin.ConfigDisplayName.Value;
				if (!string.IsNullOrEmpty(value))
				{
					__result.nameOverride = value;
				}
			}
			if (__result.nameOverride != null)
			{
				__result = new NetworkPlayerName
				{
					nameOverride = __result.nameOverride,
					playerId = new PlatformID(0uL)
				};
			}
		}
	}
	[HarmonyPatch(typeof(NetworkPlayerName), "GetResolvedName")]
	public static class ResolveNamePatch
	{
		private static bool Prefix(ref NetworkPlayerName __instance, ref string __result)
		{
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			if (!string.IsNullOrEmpty(__instance.nameOverride))
			{
				__result = __instance.nameOverride;
				return false;
			}
			ulong num = (ulong)((PlatformID)(ref __instance.playerId)).value;
			__result = ((num != 0L) ? ("Player_" + num % 10000) : "Player");
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "PlatformAuth")]
	public static class PlatformAuthPatch
	{
		private static bool Prefix(ref ClientAuthData authData, NetworkConnection conn)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			if (conn is SteamNetworkConnection)
			{
				return true;
			}
			string text = Plugin.ConfigDisplayName.Value;
			if (string.IsNullOrEmpty(text))
			{
				text = "Player_" + Random.Range(1000, 9999);
			}
			authData.platformId = new PlatformID(text);
			authData.authTicket = new byte[1];
			authData.entitlements = Array.Empty<string>();
			Plugin.Log.LogInfo((object)("Direct connect auth: name=\"" + text + "\""));
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "AddPlayerIdFromPlatform")]
	public static class AddPlayerIdFromPlatformPatch
	{
		private static bool Prefix(NetworkConnection conn, byte playerControllerId, ref NetworkUserId __result)
		{
			//IL_0041: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			ClientAuthData val = ServerAuthManager.FindAuthData(conn);
			if (val != null && val.platformId != PlatformID.nil)
			{
				__result = new NetworkUserId(val.platformId, playerControllerId);
			}
			else
			{
				__result = NetworkUserId.FromIp(conn.address, playerControllerId);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "PlatformHost")]
	public static class PlatformHostPatch
	{
		private static bool Prefix(ConCommandArgs args)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				return false;
			}
			bool argBool = ((ConCommandArgs)(ref args)).GetArgBool(0);
			if (NetworkServer.active)
			{
				Plugin.Log.LogWarning((object)"Server is already active.");
				return false;
			}
			int intValue = SvMaxPlayersConVar.instance.intValue;
			NetworkManagerSystem.singleton.desiredHost = new HostDescription(new HostingParameters
			{
				listen = argBool,
				maxPlayers = intValue
			});
			Plugin.Log.LogInfo((object)$"Direct host started: listen={argBool}, maxPlayers={intValue}");
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "UpdateServer")]
	public static class UpdateServerPatch
	{
		private static bool Prefix(NetworkManagerSystemSteam __instance)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return false;
			}
			ReadOnlyCollection<NetworkConnection> connections = NetworkServer.connections;
			for (int num = connections.Count - 1; num >= 0; num--)
			{
				NetworkConnection val = connections[num];
				if (val != null)
				{
					SteamNetworkConnection val2 = (SteamNetworkConnection)(object)((val is SteamNetworkConnection) ? val : null);
					if (val2 != null)
					{
						P2PSessionState val3 = default(P2PSessionState);
						if (((BaseSteamworks)Client.Instance).Networking.GetP2PSessionState(val2.steamId.ID, ref val3) && val3.Connecting == 0 && val3.ConnectionActive == 0)
						{
							AccessTools.Method(typeof(NetworkManagerSystemSteam), "ServerHandleClientDisconnect", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { val2 });
						}
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "InitPlatformServer")]
	public static class InitPlatformServerPatch
	{
		private static bool Prefix()
		{
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			Plugin.Log.LogInfo((object)"Skipped SteamworksServerManager.StartServer() and InitP2P() — direct connect mode.");
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManagerSystemSteam), "InitP2P")]
	public static class InitP2PPatch
	{
		private static bool Prefix()
		{
			if (!Plugin.DirectConnectActive)
			{
				return true;
			}
			Plugin.Log.LogInfo((object)"Skipped Steam P2P initialization — direct c