Decompiled source of Scrubbed Title Screen v1.1.1

BepInEx/plugins/Scrubbed_Title_Screen.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NetworkingUtils;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Scrubbed_Title_Screen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3")]
[assembly: AssemblyProduct("Scrubbed_Title_Screen")]
[assembly: AssemblyTitle("Scrubbed_Title_Screen")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("1.2.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 JPValheim.ScrubbedTitleScreen
{
	internal static class CurrentServer
	{
		private static ServerJoinData _requested;

		private static ServerJoinData _connected;

		private static ZNet _network;

		internal static void Joining(ServerJoinData server)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			_requested = server;
		}

		internal static void Connected(ZNet network, ZRpc rpc)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)network) && !network.IsServer() && (int)ZNet.GetConnectionStatus() == 2 && network.GetServerPeer()?.m_rpc == rpc)
			{
				_network = network;
				_connected = _requested;
			}
		}

		internal static bool IsConfigured(ServerTarget server)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Invalid comparison between Unknown and I4
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if (server == null || !Object.op_Implicit((Object)(object)_network) || (Object)(object)_network != (Object)(object)ZNet.instance || _network.IsServer() || (int)ZNet.GetConnectionStatus() != 2)
			{
				return false;
			}
			if (JoinNative.Matches(_connected, server))
			{
				return true;
			}
			if (!((ServerJoinData)(ref _connected)).IsValid || !Object.op_Implicit((Object)(object)MultiBackendMatchmaking.Instance))
			{
				return false;
			}
			if ((int)_connected.m_type == 3 && ((ServerJoinData)(ref _connected)).Dedicated.m_port != server.Port)
			{
				return false;
			}
			ServerJoinData val = default(ServerJoinData);
			((ServerJoinData)(ref val))..ctor(new ServerJoinDataDedicated(server.Host, server.Port));
			IPv6Address? val2 = default(IPv6Address?);
			IPv6Address? val3 = default(IPv6Address?);
			if ((int)_connected.m_type == 3 && ((ServerJoinData)(ref _connected)).Dedicated.m_port == server.Port && MultiBackendMatchmaking.GetServerIPCached(((ServerJoinData)(ref _connected)).Dedicated, ref val2) && MultiBackendMatchmaking.GetServerIPCached(((ServerJoinData)(ref val)).Dedicated, ref val3) && val2.HasValue && val3.HasValue)
			{
				IPv6Address value = val2.Value;
				if (((IPv6Address)(ref value)).Equals(val3.Value))
				{
					return true;
				}
			}
			ServerMatchmakingData serverMatchmakingData = MultiBackendMatchmaking.GetServerMatchmakingData(_connected, default(DateTime));
			ServerMatchmakingData serverMatchmakingData2 = MultiBackendMatchmaking.GetServerMatchmakingData(val, default(DateTime));
			if (!string.IsNullOrEmpty(serverMatchmakingData.m_joinCode) && !string.IsNullOrEmpty(serverMatchmakingData2.m_joinCode))
			{
				return serverMatchmakingData.m_joinCode == serverMatchmakingData2.m_joinCode;
			}
			if ((int)_connected.m_type == 1)
			{
				PlatformUserID hostUser = serverMatchmakingData.m_hostUser;
				if (((PlatformUserID)(ref hostUser)).IsValid)
				{
					hostUser = serverMatchmakingData2.m_hostUser;
					if (((PlatformUserID)(ref hostUser)).IsValid)
					{
						return serverMatchmakingData.m_hostUser == serverMatchmakingData2.m_hostUser;
					}
				}
			}
			return false;
		}

		internal static void Destroyed(ZNet network)
		{
			//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)
			if (!((Object)(object)_network != (Object)(object)network))
			{
				_network = null;
				_connected = ServerJoinData.None;
			}
		}

		internal static void Clear()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			_requested = (_connected = ServerJoinData.None);
			_network = null;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	internal static class FejdStartupSetupGuiPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(FejdStartup __instance)
		{
			TitleScreenScrubber.Apply(__instance);
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "Start")]
	internal static class FejdStartupStartPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(FejdStartup __instance)
		{
			TitleScreenScrubber.Apply(__instance);
			QuickJoin.FrontendReady();
		}
	}
	internal static class JoinNative
	{
		private static readonly FieldInfo QueuedServer = AccessTools.Field(typeof(FejdStartup), "m_queuedJoinServer");

		private static readonly FieldInfo RequestedServer = AccessTools.Field(typeof(ZSteamMatchmaking), "m_joinData");

		private static readonly MethodInfo SetPassword = AccessTools.PropertySetter(typeof(FejdStartup), "ServerPassword");

		private static readonly FieldInfo Profiles = AccessTools.Field(typeof(FejdStartup), "m_profiles");

		private static readonly FieldInfo ProfileIndex = AccessTools.Field(typeof(FejdStartup), "m_profileIndex");

		private static readonly MethodInfo UpdateCharacters = AccessTools.Method(typeof(FejdStartup), "UpdateCharacterList", (Type[])null, (Type[])null);

		internal static void Validate()
		{
			if (QueuedServer == null || RequestedServer == null || SetPassword == null || Profiles == null || ProfileIndex == null || UpdateCharacters == null)
			{
				throw new MissingMemberException("Valheim's queued-join/password API changed.");
			}
		}

		internal static bool Matches(ServerJoinData data, ServerTarget server)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (server != null && (int)data.m_type == 3 && ((ServerJoinData)(ref data)).Dedicated.m_port == server.Port)
			{
				ServerJoinDataDedicated dedicated = ((ServerJoinData)(ref data)).Dedicated;
				return string.Equals(((ServerJoinDataDedicated)(ref dedicated)).m_host, server.Host, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		internal static ServerJoinData Queued(FejdStartup startup)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return (ServerJoinData)QueuedServer.GetValue(startup);
		}

		internal static void Password(string value)
		{
			SetPassword.Invoke(null, new object[1] { value });
		}

		internal static bool SelectMostRecentCharacter(FejdStartup startup)
		{
			string text = PlatformPrefs.GetString("profile", "");
			if (string.IsNullOrEmpty(text) || !(Profiles.GetValue(startup) is List<PlayerProfile> list))
			{
				return false;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].GetFilename() != text))
				{
					ProfileIndex.SetValue(startup, i);
					UpdateCharacters.Invoke(startup, null);
					return true;
				}
			}
			return false;
		}

		internal static bool SelectCurrentCharacter(FejdStartup startup, JoinAttempt attempt)
		{
			if (attempt.CharacterFilename == null || !(Profiles.GetValue(startup) is List<PlayerProfile> list))
			{
				return false;
			}
			for (int i = 0; i < list.Count; i++)
			{
				PlayerProfile val = list[i];
				if (val.GetPlayerID() == attempt.CharacterId && !(val.GetFilename() != attempt.CharacterFilename) && !(((object)Unsafe.As<FileSource, FileSource>(ref val.m_fileSource)/*cast due to .constrained prefix*/).ToString() != attempt.CharacterSource))
				{
					ProfileIndex.SetValue(startup, i);
					UpdateCharacters.Invoke(startup, null);
					return true;
				}
			}
			return false;
		}

		internal static void ClearRequest(ServerTarget server)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			ZSteamMatchmaking instance = ZSteamMatchmaking.instance;
			if (instance != null && Matches((ServerJoinData)RequestedServer.GetValue(instance), server))
			{
				RequestedServer.SetValue(instance, ServerJoinData.None);
			}
			FejdStartup instance2 = FejdStartup.instance;
			if (Object.op_Implicit((Object)(object)instance2) && Matches(Queued(instance2), server))
			{
				QueuedServer.SetValue(instance2, ServerJoinData.None);
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ProceedJoinRequest")]
	internal static class JoinRequestPatch
	{
		private static void Prefix(ServerJoinData joinData)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (QuickJoin.Attempt != null && !JoinNative.Matches(joinData, QuickJoin.Attempt.Server))
			{
				QuickJoin.Cancel();
			}
		}

		private static void Postfix(FejdStartup __instance, ServerJoinData joinData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			QuickJoin.Accepted(__instance, joinData);
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "JoinServer")]
	internal static class JoiningPatch
	{
		private static void Prefix(FejdStartup __instance)
		{
			//IL_0001: 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)
			CurrentServer.Joining(__instance.GetServerToJoin());
			if (QuickJoin.Attempt != null)
			{
				if (JoinNative.Matches(__instance.GetServerToJoin(), QuickJoin.Attempt.Server))
				{
					QuickJoin.Attempt.Stage = JoinStage.Connecting;
				}
				else
				{
					QuickJoin.Cancel();
				}
			}
		}

		private static void Postfix(FejdStartup __instance)
		{
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting && !((MonoBehaviour)__instance).IsInvoking("LoadMainSceneIfBackendSelected") && !__instance.m_loading.activeSelf)
			{
				QuickJoin.Cancel();
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "OnSelelectCharacterBack")]
	internal static class CharacterBackPatch
	{
		private static void Prefix()
		{
			QuickJoin.Cancel();
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError", new Type[] { typeof(ConnectionStatus) })]
	internal static class ConnectionFailurePatch
	{
		private static void Prefix()
		{
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting)
			{
				QuickJoin.Cancel();
			}
		}
	}
	[HarmonyPatch(typeof(EulaWindow), "DeclineButton")]
	internal static class EulaDeclinedPatch
	{
		private static void Prefix()
		{
			QuickJoin.Cancel();
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")]
	internal static class PasswordPatch
	{
		internal struct Scope
		{
			internal bool Changed;

			internal string Previous;
		}

		private static void Prefix(ZNet __instance, ZRpc rpc, bool needPassword, out Scope __state)
		{
			__state = default(Scope);
			if (__instance.IsServer())
			{
				return;
			}
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting && __instance.GetPeers().Exists((ZNetPeer peer) => peer.m_server && peer.m_rpc == rpc))
			{
				QuickJoin.Attempt.Network = __instance;
				if (needPassword)
				{
					__state = new Scope
					{
						Changed = true,
						Previous = FejdStartup.ServerPassword
					};
					JoinNative.Password(QuickJoin.CanSupplyPassword ? QuickJoin.Attempt.Server.Password : null);
				}
			}
		}

		private static Exception Finalizer(Exception __exception, Scope __state)
		{
			if (__state.Changed)
			{
				JoinNative.Password(__state.Previous);
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	internal static class ConnectedPatch
	{
		private static void Postfix(ZNet __instance, ZRpc rpc)
		{
			CurrentServer.Connected(__instance, rpc);
			QuickJoin.Success(__instance, rpc);
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_Error")]
	internal static class ErrorPatch
	{
		private static void Prefix(ZNet __instance, ZRpc rpc, int error)
		{
			QuickJoin.Error(__instance, rpc, error);
		}
	}
	[HarmonyPatch(typeof(Game), "ContinueLogout")]
	internal static class LogoutDecisionPatch
	{
		private static void Postfix(Game __instance)
		{
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.LeavingWorld && !__instance.IsShuttingDown())
			{
				QuickJoin.Cancel();
			}
		}
	}
	[HarmonyPatch(typeof(Menu), "OnLogoutNo")]
	internal static class LogoutCancelPatch
	{
		private static void Prefix()
		{
			QuickJoin.Cancel();
		}
	}
	[HarmonyPatch(typeof(Menu), "Hide")]
	internal static class LeaveMenuPatch
	{
		private static void Prefix()
		{
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.LeavingWorld && Object.op_Implicit((Object)(object)Game.instance) && !Game.instance.IsShuttingDown())
			{
				QuickJoin.Cancel();
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnDestroy")]
	internal static class NetworkDestroyedPatch
	{
		private static void Prefix(ZNet __instance)
		{
			CurrentServer.Destroyed(__instance);
			JoinAttempt attempt = QuickJoin.Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting && (Object)(object)QuickJoin.Attempt.Network == (Object)(object)__instance)
			{
				QuickJoin.Cancel();
			}
		}
	}
	internal static class PauseJoinButton
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__ConfirmSwitch;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static PopupButtonCallback <>9__4_1;

			internal void <ConfirmSwitch>b__4_1()
			{
				UnifiedPopup.Pop();
			}
		}

		private static Button _button;

		private static Menu _menu;

		private static float _fontSize;

		internal static void Refresh(Menu menu)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00b4: 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_00bf: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: 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)
			if (!Object.op_Implicit((Object)(object)menu) || !Object.op_Implicit((Object)(object)menu.menuEntriesParent) || !Object.op_Implicit((Object)(object)menu.m_logoutButton))
			{
				return;
			}
			ServerTarget target;
			bool flag = QuickJoin.GetServer(out target) && !CurrentServer.IsConfigured(target);
			if ((Object)(object)_menu != (Object)(object)menu)
			{
				Destroy();
			}
			if (!Object.op_Implicit((Object)(object)_button) && flag)
			{
				_menu = menu;
				_button = Object.Instantiate<Button>(menu.m_logoutButton, (Transform)(object)menu.menuEntriesParent, false);
				((Object)_button).name = "ScrubbedTitleScreen_Server";
				_button.onClick = new ButtonClickedEvent();
				ButtonClickedEvent onClick = _button.onClick;
				object obj = <>O.<0>__ConfirmSwitch;
				if (obj == null)
				{
					UnityAction val = ConfirmSwitch;
					<>O.<0>__ConfirmSwitch = val;
					obj = (object)val;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
				((Component)_button).transform.SetAsLastSibling();
				TMP_Text componentInChildren = ((Component)_button).GetComponentInChildren<TMP_Text>(true);
				_fontSize = (Object.op_Implicit((Object)(object)componentInChildren) ? (componentInChildren.fontSize * 0.75f) : 18f);
				LayoutElement obj2 = ((Component)_button).GetComponent<LayoutElement>() ?? ((Component)_button).gameObject.AddComponent<LayoutElement>();
				obj2.minHeight = 30f;
				obj2.preferredHeight = 30f;
				obj2.flexibleHeight = 0f;
				Image[] componentsInChildren = ((Component)_button).GetComponentsInChildren<Image>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					((Selectable)_button).targetGraphic = (Graphic)(object)componentInChildren;
				}
				ColorBlock colors = ((Selectable)_button).colors;
				Color val2 = (((ColorBlock)(ref colors)).selectedColor = Color.white);
				Color val3 = (((ColorBlock)(ref colors)).pressedColor = val2);
				Color normalColor = (((ColorBlock)(ref colors)).highlightedColor = val3);
				((ColorBlock)(ref colors)).normalColor = normalColor;
				((ColorBlock)(ref colors)).disabledColor = new Color(1f, 1f, 1f, 0.4f);
				((Selectable)_button).colors = colors;
			}
			if (Object.op_Implicit((Object)(object)_button))
			{
				((Component)_button).gameObject.SetActive(flag);
				((Selectable)_button).interactable = QuickJoin.Attempt == null;
				TMP_Text componentInChildren2 = ((Component)_button).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren2) && flag)
				{
					componentInChildren2.text = target.Name;
					componentInChildren2.richText = false;
					componentInChildren2.enableAutoSizing = false;
					componentInChildren2.fontSize = _fontSize;
					((Graphic)componentInChildren2).color = Color.white;
					((Graphic)componentInChildren2).raycastTarget = true;
				}
				LayoutRebuilder.ForceRebuildLayoutImmediate(menu.menuEntriesParent);
				Navigation(menu);
			}
		}

		private static void ConfirmSwitch()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			Menu menu = _menu;
			if (!Object.op_Implicit((Object)(object)menu) || !((Component)menu.m_menuDialog).gameObject.activeInHierarchy || UnifiedPopup.IsVisible() || !UnifiedPopup.IsAvailable() || QuickJoin.Attempt != null || !QuickJoin.GetServer(out var server) || CurrentServer.IsConfigured(server))
			{
				return;
			}
			string name = server.Name;
			string text = "Do you want to log out and log in to the " + server.Name + " server?";
			PopupButtonCallback val = delegate
			{
				UnifiedPopup.Pop();
				QuickJoin.Switch(server, menu);
			};
			object obj = <>c.<>9__4_1;
			if (obj == null)
			{
				PopupButtonCallback val2 = delegate
				{
					UnifiedPopup.Pop();
				};
				<>c.<>9__4_1 = val2;
				obj = (object)val2;
			}
			UnifiedPopup.Push((PopupBase)new YesNoPopup(name, text, val, (PopupButtonCallback)obj, false, true));
			SwitchConfirmation.Apply();
		}

		internal static void Navigation(Menu menu)
		{
			//IL_0064: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_menu != (Object)(object)menu) && Object.op_Implicit((Object)(object)_button))
			{
				Button val = ((Object.op_Implicit((Object)(object)menu.m_quitButton) && ((Component)menu.m_quitButton).gameObject.activeSelf) ? menu.m_quitButton : menu.m_logoutButton);
				Button continueButton = menu.m_continueButton;
				bool activeSelf = ((Component)_button).gameObject.activeSelf;
				Navigation navigation = ((Selectable)_button).navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)val;
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)continueButton;
				((Selectable)_button).navigation = navigation;
				navigation = ((Selectable)val).navigation;
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)(activeSelf ? _button : continueButton);
				((Selectable)val).navigation = navigation;
				navigation = ((Selectable)continueButton).navigation;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)(activeSelf ? _button : val);
				((Selectable)continueButton).navigation = navigation;
			}
		}

		internal static void Destroy()
		{
			if (Object.op_Implicit((Object)(object)_button))
			{
				Object.Destroy((Object)(object)((Component)_button).gameObject);
			}
			_button = null;
			_menu = null;
		}
	}
	[HarmonyPatch(typeof(Menu), "Start")]
	internal static class MenuStartPatch
	{
		private static void Postfix(Menu __instance)
		{
			PauseJoinButton.Refresh(__instance);
		}
	}
	[HarmonyPatch(typeof(Menu), "Show")]
	internal static class MenuShowPatch
	{
		private static void Postfix(Menu __instance)
		{
			PauseJoinButton.Refresh(__instance);
		}
	}
	[HarmonyPatch(typeof(Menu), "UpdateNavigation")]
	internal static class MenuNavigationPatch
	{
		private static void Postfix(Menu __instance)
		{
			PauseJoinButton.Navigation(__instance);
		}
	}
	[BepInPlugin("com.jpvalheim.scrubbedtitlescreen", "Scrubbed_Title_Screen", "1.2.3")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static EventHandler <0>__OnImageSettingChanged;

			public static UnityAction <1>__JoinFromLogo;
		}

		public const string PluginGuid = "com.jpvalheim.scrubbedtitlescreen";

		public const string PluginName = "Scrubbed_Title_Screen";

		public const string PluginVersion = "1.2.3";

		private const string CustomImageObjectName = "ScrubbedTitleScreen_CustomImage";

		private static Plugin _instance;

		private static ConfigEntry<bool> _customImageEnabled;

		private static ConfigEntry<string> _customImageFile;

		private static ConfigEntry<ScreenAnchor> _customImageAnchor;

		private static ConfigEntry<float> _customImageOffsetX;

		private static ConfigEntry<float> _customImageOffsetY;

		private static ConfigEntry<float> _customImageScale;

		private static GameObject _customImageObject;

		private static Texture2D _customImageTexture;

		private static Texture2D _hoverImageTexture;

		private static string _loadedHoverImagePath;

		private static DateTime _loadedHoverImageWriteTimeUtc;

		private static string _lastHoverImageWarning;

		private static string _loadedImagePath;

		private static DateTime _loadedImageWriteTimeUtc;

		private static string _lastImageWarning;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			_instance = this;
			BindConfiguration();
			QuickJoin.Initialize(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.jpvalheim.scrubbedtitlescreen");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Scrubbed_Title_Screen 1.2.3 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			UnbindConfiguration();
			QuickJoin.Dispose();
			DestroyCustomImage();
			_instance = null;
		}

		private void BindConfiguration()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			_customImageEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Custom title image", "Enabled", false, "Displays a PNG image on the title screen.");
			_customImageFile = ((BaseUnityPlugin)this).Config.Bind<string>("Custom title image", "PNG file", "Scrubbed_Title_Screen/TitleImage.png", "PNG path. Relative paths are resolved from BepInEx/config; absolute paths are also accepted.");
			_customImageAnchor = ((BaseUnityPlugin)this).Config.Bind<ScreenAnchor>("Custom title image", "Anchor", ScreenAnchor.TopCenter, "Placement point used as the image anchor on the title screen.");
			_customImageOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Custom title image", "Offset X", 0f, "Horizontal offset from the selected anchor in UI pixels. Positive values move right.");
			_customImageOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Custom title image", "Offset Y", -40f, "Vertical offset from the selected anchor in UI pixels. Positive values move up.");
			_customImageScale = ((BaseUnityPlugin)this).Config.Bind<float>("Custom title image", "Scale", 0.35f, new ConfigDescription("Multiplier applied to the PNG's native width and height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
			Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "Scrubbed_Title_Screen"));
			_customImageEnabled.SettingChanged += OnImageSettingChanged;
			_customImageFile.SettingChanged += OnImageSettingChanged;
			_customImageAnchor.SettingChanged += OnImageSettingChanged;
			_customImageOffsetX.SettingChanged += OnImageSettingChanged;
			_customImageOffsetY.SettingChanged += OnImageSettingChanged;
			_customImageScale.SettingChanged += OnImageSettingChanged;
		}

		private static void UnbindConfiguration()
		{
			if (_customImageEnabled != null)
			{
				_customImageEnabled.SettingChanged -= OnImageSettingChanged;
				_customImageFile.SettingChanged -= OnImageSettingChanged;
				_customImageAnchor.SettingChanged -= OnImageSettingChanged;
				_customImageOffsetX.SettingChanged -= OnImageSettingChanged;
				_customImageOffsetY.SettingChanged -= OnImageSettingChanged;
				_customImageScale.SettingChanged -= OnImageSettingChanged;
			}
		}

		private static void OnImageSettingChanged(object sender, EventArgs args)
		{
			RefreshCustomImage(FejdStartup.instance);
		}

		internal static void RefreshCustomImage(FejdStartup startup, bool forceReload = false)
		{
			if (_customImageEnabled == null || !_customImageEnabled.Value || (Object)(object)startup == (Object)null || (Object)(object)startup.m_mainMenu == (Object)null)
			{
				DestroyCustomImage();
				return;
			}
			string text = ResolveImagePath(_customImageFile.Value);
			if (!string.Equals(Path.GetExtension(text), ".png", StringComparison.OrdinalIgnoreCase))
			{
				DestroyCustomImage();
				WarnImageOnce("Custom title image must be a PNG: " + text);
				return;
			}
			if (!File.Exists(text))
			{
				DestroyCustomImage();
				WarnImageOnce("Custom title image was not found: " + text);
				return;
			}
			DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(text);
			if ((!forceReload && !((Object)(object)_customImageTexture == (Object)null) && string.Equals(_loadedImagePath, text, StringComparison.OrdinalIgnoreCase) && !(_loadedImageWriteTimeUtc != lastWriteTimeUtc)) || TryLoadTexture(text, lastWriteTimeUtc))
			{
				RefreshHoverTexture(text, forceReload);
				EnsureImageObject(startup.m_mainMenu.transform);
				ApplyImageLayout();
				_lastImageWarning = null;
			}
		}

		private static bool TryLoadTexture(string imagePath, DateTime writeTimeUtc)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			try
			{
				byte[] array = File.ReadAllBytes(imagePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array, false))
				{
					Object.Destroy((Object)(object)val);
					WarnImageOnce("Custom title image could not be decoded as PNG: " + imagePath);
					return false;
				}
				((Object)val).name = Path.GetFileNameWithoutExtension(imagePath);
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				if ((Object)(object)_customImageTexture != (Object)null)
				{
					Object.Destroy((Object)(object)_customImageTexture);
				}
				_customImageTexture = val;
				_loadedImagePath = imagePath;
				_loadedImageWriteTimeUtc = writeTimeUtc;
				if ((Object)(object)_customImageObject != (Object)null)
				{
					_customImageObject.GetComponent<RawImage>().texture = (Texture)(object)val;
				}
				Plugin instance = _instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)$"Loaded custom title image '{imagePath}' ({((Texture)val).width}x{((Texture)val).height}).");
				}
				return true;
			}
			catch (Exception ex)
			{
				DestroyCustomImage();
				WarnImageOnce("Custom title image failed to load: " + ex.Message);
				return false;
			}
		}

		private static void RefreshHoverTexture(string imagePath, bool forceReload)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			string text = TitleImageRollover.CompanionPath(imagePath);
			if (!File.Exists(text))
			{
				ClearHoverTexture();
				_lastHoverImageWarning = null;
				return;
			}
			Texture2D val = null;
			try
			{
				DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(text);
				if (forceReload || !((Object)(object)_hoverImageTexture != (Object)null) || !string.Equals(_loadedHoverImagePath, text, StringComparison.Ordinal) || !(_loadedHoverImageWriteTimeUtc == lastWriteTimeUtc))
				{
					val = new Texture2D(2, 2, (TextureFormat)4, false);
					if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), false))
					{
						throw new InvalidDataException("The file could not be decoded as PNG.");
					}
					((Object)val).name = Path.GetFileNameWithoutExtension(text);
					((Texture)val).wrapMode = (TextureWrapMode)1;
					((Texture)val).filterMode = (FilterMode)1;
					ClearHoverTexture();
					_hoverImageTexture = val;
					_loadedHoverImagePath = text;
					_loadedHoverImageWriteTimeUtc = lastWriteTimeUtc;
					_lastHoverImageWarning = null;
				}
			}
			catch (Exception ex)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
				ClearHoverTexture();
				string text2 = "Custom title hover image failed to load: " + text + ": " + ex.Message;
				if (_lastHoverImageWarning != text2)
				{
					_lastHoverImageWarning = text2;
					Warn(text2);
				}
			}
		}

		private static void ClearHoverTexture()
		{
			if ((Object)(object)_hoverImageTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_hoverImageTexture);
			}
			_hoverImageTexture = null;
			_loadedHoverImagePath = null;
			_loadedHoverImageWriteTimeUtc = default(DateTime);
		}

		private static void EnsureImageObject(Transform parent)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			if ((Object)(object)_customImageObject == (Object)null)
			{
				_customImageObject = new GameObject("ScrubbedTitleScreen_CustomImage", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(RawImage)
				});
				RawImage component = _customImageObject.GetComponent<RawImage>();
				component.texture = (Texture)(object)_customImageTexture;
				Button obj = _customImageObject.AddComponent<Button>();
				((Selectable)obj).targetGraphic = (Graphic)(object)component;
				((Selectable)obj).transition = (Transition)0;
				Navigation navigation = default(Navigation);
				((Navigation)(ref navigation)).mode = (Mode)0;
				((Selectable)obj).navigation = navigation;
				ButtonClickedEvent onClick = obj.onClick;
				object obj2 = <>O.<1>__JoinFromLogo;
				if (obj2 == null)
				{
					UnityAction val = QuickJoin.JoinFromLogo;
					<>O.<1>__JoinFromLogo = val;
					obj2 = (object)val;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj2);
				_customImageObject.AddComponent<TitleImageRollover>();
			}
			bool hasServer = QuickJoin.HasServer;
			RawImage component2 = _customImageObject.GetComponent<RawImage>();
			((Graphic)component2).raycastTarget = hasServer || (Object)(object)_hoverImageTexture != (Object)null;
			_customImageObject.GetComponent<TitleImageRollover>().Configure(component2, (Texture)(object)_customImageTexture, (Texture)(object)_hoverImageTexture);
			((Selectable)_customImageObject.GetComponent<Button>()).interactable = hasServer;
			_customImageObject.layer = ((Component)parent).gameObject.layer;
			_customImageObject.transform.SetParent(parent, false);
			_customImageObject.transform.SetAsLastSibling();
			_customImageObject.SetActive(true);
		}

		private static void ApplyImageLayout()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_customImageObject == (Object)null) && !((Object)(object)_customImageTexture == (Object)null))
			{
				Vector2 anchorPoint = GetAnchorPoint(_customImageAnchor.Value);
				RectTransform component = _customImageObject.GetComponent<RectTransform>();
				component.anchorMin = anchorPoint;
				component.anchorMax = anchorPoint;
				component.pivot = anchorPoint;
				component.anchoredPosition = new Vector2(_customImageOffsetX.Value, _customImageOffsetY.Value);
				((Transform)component).localScale = Vector3.one;
				((Transform)component).localRotation = Quaternion.identity;
				component.sizeDelta = new Vector2((float)((Texture)_customImageTexture).width * _customImageScale.Value, (float)((Texture)_customImageTexture).height * _customImageScale.Value);
			}
		}

		private static Vector2 GetAnchorPoint(ScreenAnchor anchor)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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)
			return (Vector2)(anchor switch
			{
				ScreenAnchor.TopLeft => new Vector2(0f, 1f), 
				ScreenAnchor.TopCenter => new Vector2(0.5f, 1f), 
				ScreenAnchor.TopRight => new Vector2(1f, 1f), 
				ScreenAnchor.MiddleLeft => new Vector2(0f, 0.5f), 
				ScreenAnchor.Center => new Vector2(0.5f, 0.5f), 
				ScreenAnchor.MiddleRight => new Vector2(1f, 0.5f), 
				ScreenAnchor.BottomLeft => new Vector2(0f, 0f), 
				ScreenAnchor.BottomCenter => new Vector2(0.5f, 0f), 
				ScreenAnchor.BottomRight => new Vector2(1f, 0f), 
				_ => new Vector2(0.5f, 1f), 
			});
		}

		private static string ResolveImagePath(string configuredPath)
		{
			string text = (configuredPath ?? string.Empty).Trim();
			return Path.GetFullPath(Path.IsPathRooted(text) ? text : Path.Combine(Paths.ConfigPath, text));
		}

		private static void WarnImageOnce(string message)
		{
			if (!(_lastImageWarning == message))
			{
				_lastImageWarning = message;
				Plugin instance = _instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
				}
			}
		}

		internal static void Warn(string message)
		{
			Plugin instance = _instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
			}
		}

		private static void DestroyCustomImage()
		{
			if ((Object)(object)_customImageObject != (Object)null)
			{
				Object.Destroy((Object)(object)_customImageObject);
				_customImageObject = null;
			}
			if ((Object)(object)_customImageTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_customImageTexture);
				_customImageTexture = null;
			}
			ClearHoverTexture();
			_lastHoverImageWarning = null;
			_loadedImagePath = null;
			_loadedImageWriteTimeUtc = default(DateTime);
		}
	}
	internal enum JoinStage
	{
		Queued,
		ChoosingCharacter,
		Connecting,
		LeavingWorld
	}
	internal sealed class JoinAttempt
	{
		internal ServerTarget Server;

		internal JoinStage Stage;

		internal Game Origin;

		internal ZNet Network;

		internal long CharacterId;

		internal string CharacterFilename;

		internal string CharacterSource;

		internal bool UseRecentCharacter;
	}
	internal static class QuickJoin
	{
		private static ConfigEntry<string> _name;

		private static ConfigEntry<string> _address;

		private static ConfigEntry<string> _password;

		internal static JoinAttempt Attempt;

		private static string _rejectedEndpoint;

		private static string _rejectedPassword;

		internal static bool HasServer
		{
			get
			{
				ServerTarget target;
				return ReadServer(out target);
			}
		}

		internal static bool CanSupplyPassword
		{
			get
			{
				JoinAttempt attempt = Attempt;
				if (attempt != null && attempt.Stage == JoinStage.Connecting && !string.IsNullOrEmpty(Attempt.Server.Password))
				{
					if (!(_rejectedEndpoint != Attempt.Server.Endpoint))
					{
						return _rejectedPassword != Attempt.Server.Password;
					}
					return true;
				}
				return false;
			}
		}

		internal static void Initialize(ConfigFile config)
		{
			JoinNative.Validate();
			_name = config.Bind<string>("Server", "Name", "", "Server name shown at the bottom of the pause menu. Blank uses the hostname.");
			_address = config.Bind<string>("Server", "Address", "", "Server IP or hostname, optionally followed by :port (default 2456). Blank disables both join shortcuts.");
			_password = config.Bind<string>("Server", "Password", "", "Password entered automatically for this server. Blank keeps the normal password prompt.");
			_name.SettingChanged += SettingsChanged;
			_address.SettingChanged += SettingsChanged;
			_password.SettingChanged += SettingsChanged;
			if (!string.IsNullOrWhiteSpace(_address.Value) && !HasServer)
			{
				Plugin.Warn("Server Address is invalid; join shortcuts are disabled.");
			}
		}

		private static bool ReadServer(out ServerTarget target)
		{
			return ServerTarget.TryCreate(_name?.Value, _address?.Value, _password?.Value, out target);
		}

		private static void SettingsChanged(object sender, EventArgs args)
		{
			Plugin.RefreshCustomImage(FejdStartup.instance);
			PauseJoinButton.Refresh(Menu.instance);
		}

		internal static void Dispose()
		{
			SwitchConfirmation.Restore();
			CurrentServer.Clear();
			Cancel();
			_name.SettingChanged -= SettingsChanged;
			_address.SettingChanged -= SettingsChanged;
			_password.SettingChanged -= SettingsChanged;
			PauseJoinButton.Destroy();
			_rejectedEndpoint = (_rejectedPassword = null);
		}

		internal static bool GetServer(out ServerTarget target)
		{
			return ReadServer(out target);
		}

		internal static void JoinFromLogo()
		{
			FejdStartup instance = FejdStartup.instance;
			if (Object.op_Implicit((Object)(object)instance) && instance.m_mainMenu.activeInHierarchy && (!Object.op_Implicit((Object)(object)instance.m_changeLog) || !instance.m_changeLog.activeInHierarchy) && !UnifiedPopup.IsVisible() && Attempt == null && ZSteamMatchmaking.instance != null && ReadServer(out var target))
			{
				Attempt = new JoinAttempt
				{
					Server = target,
					Stage = JoinStage.Queued,
					UseRecentCharacter = true
				};
				ZSteamMatchmaking.instance.QueueServerJoin(target.Endpoint);
			}
		}

		internal static void Switch(ServerTarget target, Menu menu)
		{
			if (Attempt == null && Object.op_Implicit((Object)(object)menu) && Object.op_Implicit((Object)(object)Game.instance) && !Game.instance.IsShuttingDown())
			{
				Attempt = new JoinAttempt
				{
					Server = target,
					Stage = JoinStage.LeavingWorld,
					Origin = Game.instance
				};
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				if (playerProfile != null)
				{
					Attempt.CharacterId = playerProfile.GetPlayerID();
					Attempt.CharacterFilename = playerProfile.GetFilename();
					Attempt.CharacterSource = ((object)Unsafe.As<FileSource, FileSource>(ref playerProfile.m_fileSource)/*cast due to .constrained prefix*/).ToString();
				}
				menu.OnLogoutYes();
			}
		}

		internal static void FrontendReady()
		{
			JoinAttempt attempt = Attempt;
			if (attempt != null && attempt.Stage == JoinStage.LeavingWorld && !Object.op_Implicit((Object)(object)Attempt.Origin) && !Object.op_Implicit((Object)(object)Game.instance) && ZSteamMatchmaking.instance != null)
			{
				Attempt.Stage = JoinStage.Queued;
				ZSteamMatchmaking.instance.QueueServerJoin(Attempt.Server.Endpoint);
			}
			else
			{
				Cancel();
			}
		}

		internal static void Cancel()
		{
			if (Attempt != null)
			{
				JoinNative.ClearRequest(Attempt.Server);
			}
			Attempt = null;
		}

		internal static void Accepted(FejdStartup startup, ServerJoinData requested)
		{
			//IL_0016: 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)
			JoinAttempt attempt = Attempt;
			if (attempt == null || attempt.Stage != JoinStage.Queued || !JoinNative.Matches(requested, Attempt.Server))
			{
				return;
			}
			if (JoinNative.Matches(JoinNative.Queued(startup), Attempt.Server))
			{
				Attempt.Stage = JoinStage.ChoosingCharacter;
				if (Attempt.UseRecentCharacter ? JoinNative.SelectMostRecentCharacter(startup) : JoinNative.SelectCurrentCharacter(startup, Attempt))
				{
					startup.OnCharacterStart();
				}
			}
			else
			{
				Cancel();
			}
		}

		internal static void Success(ZNet net, ZRpc rpc)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			JoinAttempt attempt = Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting && !net.IsServer() && (int)ZNet.GetConnectionStatus() == 2 && net.GetServerPeer()?.m_rpc == rpc)
			{
				_rejectedEndpoint = (_rejectedPassword = null);
				Attempt = null;
			}
		}

		internal static void Error(ZNet net, ZRpc rpc, int error)
		{
			JoinAttempt attempt = Attempt;
			if (attempt != null && attempt.Stage == JoinStage.Connecting && !net.IsServer() && net.GetPeers().Exists((ZNetPeer peer) => peer.m_server && peer.m_rpc == rpc))
			{
				if (error == 6)
				{
					_rejectedEndpoint = Attempt.Server.Endpoint;
					_rejectedPassword = Attempt.Server.Password;
				}
				Cancel();
			}
		}
	}
	public enum ScreenAnchor
	{
		TopLeft,
		TopCenter,
		TopRight,
		MiddleLeft,
		Center,
		MiddleRight,
		BottomLeft,
		BottomCenter,
		BottomRight
	}
	internal sealed class ServerTarget
	{
		internal string Name { get; }

		internal string Host { get; }

		internal ushort Port { get; }

		internal string Password { get; }

		internal string Endpoint => (Host.Contains(":") ? ("[" + Host + "]") : Host) + ":" + Port;

		private ServerTarget(string name, string host, ushort port, string password)
		{
			Name = (string.IsNullOrWhiteSpace(name) ? host : name.Trim());
			Host = host;
			Port = port;
			Password = password ?? "";
		}

		internal static bool TryCreate(string name, string address, string password, out ServerTarget target)
		{
			target = null;
			string text = (address ?? "").Trim();
			if (text.Length == 0 || text.IndexOfAny(new char[5] { '/', '\\', '@', '?', '#' }) >= 0)
			{
				return false;
			}
			string text2 = text;
			foreach (char c in text2)
			{
				if (char.IsWhiteSpace(c) || char.IsControl(c))
				{
					return false;
				}
			}
			if (!Uri.TryCreate("tcp://" + text, UriKind.Absolute, out Uri result) || result.Port == 0 || result.Port > 65535 || result.AbsolutePath != "/" || result.HostNameType == UriHostNameType.Unknown || text.EndsWith(":"))
			{
				return false;
			}
			string text3 = result.Host.Trim('[', ']');
			if (IPAddress.TryParse(text3, out IPAddress address2))
			{
				text3 = address2.ToString();
			}
			ushort port = (ushort)((result.Port < 0) ? 2456 : ((ushort)result.Port));
			target = new ServerTarget(name, text3, port, password);
			return true;
		}
	}
	internal static class SwitchConfirmation
	{
		private static readonly FieldInfo Instance = AccessTools.Field(typeof(UnifiedPopup), "instance");

		private static readonly FieldInfo Header = AccessTools.Field(typeof(UnifiedPopup), "headerText");

		private static readonly FieldInfo Cover = AccessTools.Field(typeof(UnifiedPopup), "fullScreenBackgroundCover");

		private static UnifiedPopup _popup;

		private static TMP_Text _header;

		private static CanvasGroup _cover;

		private static Coroutine _fade;

		private static float _fontSize;

		private static float _fontMin;

		private static float _fontMax;

		private static float _alpha;

		private static bool _addedGroup;

		internal static void Apply()
		{
			if (Instance == null || Header == null || Cover == null)
			{
				return;
			}
			object? value = Instance.GetValue(null);
			UnifiedPopup val = (UnifiedPopup)((value is UnifiedPopup) ? value : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Restore();
			_popup = val;
			object? value2 = Header.GetValue(val);
			_header = (TMP_Text)((value2 is TMP_Text) ? value2 : null);
			if (Object.op_Implicit((Object)(object)_header))
			{
				_fontSize = _header.fontSize;
				_fontMin = _header.fontSizeMin;
				_fontMax = _header.fontSizeMax;
				_header.fontSize = _fontSize * 1.15f;
				_header.fontSizeMin = _fontMin * 1.15f;
				_header.fontSizeMax = _fontMax * 1.15f;
			}
			object? value3 = Cover.GetValue(val);
			GameObject val2 = (GameObject)((value3 is GameObject) ? value3 : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				_cover = val2.GetComponent<CanvasGroup>();
				_addedGroup = !Object.op_Implicit((Object)(object)_cover);
				if (_addedGroup)
				{
					_cover = val2.AddComponent<CanvasGroup>();
				}
				_alpha = _cover.alpha;
				_cover.alpha = 0f;
				_fade = ((MonoBehaviour)val).StartCoroutine(FadeIn());
			}
		}

		private static IEnumerator FadeIn()
		{
			float elapsed = 0f;
			while (Object.op_Implicit((Object)(object)_cover) && elapsed < 0.25f)
			{
				yield return null;
				elapsed += Time.unscaledDeltaTime;
				if (Object.op_Implicit((Object)(object)_cover))
				{
					_cover.alpha = _alpha * Mathf.SmoothStep(0f, 1f, elapsed / 0.25f);
				}
			}
			if (Object.op_Implicit((Object)(object)_cover))
			{
				_cover.alpha = _alpha;
			}
			_fade = null;
		}

		internal static void Restore(UnifiedPopup popup = null)
		{
			if (Object.op_Implicit((Object)(object)popup) && (Object)(object)popup != (Object)(object)_popup)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_popup) && _fade != null)
			{
				((MonoBehaviour)_popup).StopCoroutine(_fade);
			}
			_fade = null;
			if (Object.op_Implicit((Object)(object)_header))
			{
				_header.fontSize = _fontSize;
				_header.fontSizeMin = _fontMin;
				_header.fontSizeMax = _fontMax;
			}
			if (Object.op_Implicit((Object)(object)_cover))
			{
				_cover.alpha = _alpha;
				if (_addedGroup)
				{
					Object.Destroy((Object)(object)_cover);
				}
			}
			_popup = null;
			_header = null;
			_cover = null;
			_addedGroup = false;
		}
	}
	[HarmonyPatch(typeof(UnifiedPopup), "Show")]
	internal static class PopupShowPatch
	{
		private static void Prefix(UnifiedPopup __instance)
		{
			SwitchConfirmation.Restore(__instance);
		}
	}
	[HarmonyPatch(typeof(UnifiedPopup), "Hide")]
	internal static class PopupHidePatch
	{
		private static void Prefix(UnifiedPopup __instance)
		{
			SwitchConfirmation.Restore(__instance);
		}
	}
	[HarmonyPatch(typeof(UnifiedPopup), "OnDisable")]
	internal static class PopupDisabledPatch
	{
		private static void Prefix(UnifiedPopup __instance)
		{
			SwitchConfirmation.Restore(__instance);
		}
	}
	internal sealed class TitleImageRollover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private RawImage _image;

		private Texture _normal;

		private Texture _hover;

		private bool _pointerInside;

		internal static string CompanionPath(string imagePath)
		{
			return Path.Combine(Path.GetDirectoryName(imagePath) ?? string.Empty, Path.GetFileNameWithoutExtension(imagePath) + "_Hover.png");
		}

		internal void Configure(RawImage image, Texture normal, Texture hover)
		{
			_image = image;
			_normal = normal;
			_hover = hover;
			Apply();
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			_pointerInside = true;
			Apply();
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			_pointerInside = false;
			Apply();
		}

		private void OnDisable()
		{
			_pointerInside = false;
			Apply();
		}

		private void Apply()
		{
			if ((Object)(object)_image != (Object)null)
			{
				_image.texture = ((_pointerInside && (Object)(object)_hover != (Object)null) ? _hover : _normal);
			}
		}
	}
	internal static class TitleScreenScrubber
	{
		internal static void Apply(FejdStartup startup)
		{
			if (!((Object)(object)startup == (Object)null))
			{
				if ((Object)(object)startup.m_moddedText != (Object)null)
				{
					startup.m_moddedText.SetActive(false);
				}
				Plugin.RefreshCustomImage(startup);
			}
		}
	}
}