Decompiled source of MMOHeimMainMenu v1.0.6

MMOHeimMainMenu.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MMOHeimMainMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Custom main menu assets, loading art rotation, and Discord link for MMOHeim.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MMOHeimMainMenu")]
[assembly: AssemblyTitle("MMOHeimMainMenu")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MMOHeimMainMenu
{
	internal static class DiscordPanelVisibility
	{
		private static ConfigEntry<bool>? _visibleOnlyOnStartMenu;

		private static bool? _lastAppliedVisible;

		internal static void BindConfig(ConfigFile config)
		{
			_visibleOnlyOnStartMenu = config.Bind<bool>("Discord Panel", "VisibleOnlyOnStartMenu", true, "When true, the Discord panel is visible only on the main Start Game screen. Hidden on character/world select and during load.");
		}

		internal static bool IsGatingEnabled()
		{
			if (_visibleOnlyOnStartMenu != null)
			{
				return _visibleOnlyOnStartMenu.Value;
			}
			return true;
		}

		internal static void RegisterPanel(GameObject? panelRoot)
		{
			MMOHeimMainMenuPlugin.SetDiscordPanelRoot(panelRoot);
		}

		internal static void Refresh(FejdStartup? fejd, string reason)
		{
			GameObject discordPanelRoot = MMOHeimMainMenuPlugin.DiscordPanelRoot;
			if (!((Object)(object)discordPanelRoot == (Object)null))
			{
				bool visible = ComputeShouldBeVisible(fejd);
				ApplyVisible(discordPanelRoot, visible, reason);
			}
		}

		internal static void Hide(string reason)
		{
			GameObject discordPanelRoot = MMOHeimMainMenuPlugin.DiscordPanelRoot;
			if (!((Object)(object)discordPanelRoot == (Object)null))
			{
				ApplyVisible(discordPanelRoot, visible: false, reason);
			}
		}

		internal static void SyncIfDrifted(FejdStartup? fejd)
		{
			if (!IsGatingEnabled() || !MMOHeimMainMenuPlugin.MainMenuActive)
			{
				return;
			}
			GameObject discordPanelRoot = MMOHeimMainMenuPlugin.DiscordPanelRoot;
			if (!((Object)(object)discordPanelRoot == (Object)null))
			{
				bool flag = ComputeShouldBeVisible(fejd);
				if (_lastAppliedVisible != flag)
				{
					ApplyVisible(discordPanelRoot, flag, "FejdStartup.LateUpdate (visibility drift)");
				}
			}
		}

		private static bool ComputeShouldBeVisible(FejdStartup? fejd)
		{
			if (!MMOHeimMainMenuPlugin.MainMenuActive)
			{
				return false;
			}
			if (!IsGatingEnabled())
			{
				return true;
			}
			if ((Object)(object)fejd == (Object)null || (Object)(object)fejd.m_mainMenu == (Object)null)
			{
				return false;
			}
			return fejd.m_mainMenu.activeInHierarchy;
		}

		private static void ApplyVisible(GameObject panel, bool visible, string reason)
		{
			if (_lastAppliedVisible != visible || panel.activeSelf != visible)
			{
				panel.SetActive(visible);
				_lastAppliedVisible = visible;
				MMOHeimMainMenuPlugin.LogInfo(string.Format("Discord panel {0} ({1}); gating={2}, mainMenuActive={3}.", visible ? "shown" : "hidden", reason, IsGatingEnabled(), IsMainMenuRootActive(FejdStartup.instance)));
			}
		}

		private static bool IsMainMenuRootActive(FejdStartup? fejd)
		{
			if ((Object)(object)fejd?.m_mainMenu != (Object)null)
			{
				return fejd.m_mainMenu.activeInHierarchy;
			}
			return false;
		}

		internal static void ResetSessionState()
		{
			_lastAppliedVisible = null;
		}
	}
	internal static class LoadingScreens
	{
		internal struct LoadingTargetResult
		{
			internal bool IsValid;

			internal bool IsRaw;

			internal Image? Image;

			internal RawImage? RawImage;

			internal int Score;

			internal string Path;

			internal string ObjectName;
		}

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

			private object <>2__current;

			public LoadingTargetResult result;

			public Sprite sprite;

			private float <deadline>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<deadline>5__2 = Time.realtimeSinceStartup + 2400f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (Time.realtimeSinceStartup < <deadline>5__2 && !MMOHeimMainMenuPlugin.TryGetLocalPlayerPresentPlain() && (Object)(object)MMOHeimMainMenuPlugin.Instance != (Object)null)
				{
					ApplyLoadingTargetResult(result, sprite);
					<>2__current = (object)new WaitForSecondsRealtime(2f);
					<>1__state = 1;
					return true;
				}
				_forceCoroutine = null;
				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 <LoadingFadeCoroutine>d__23 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public LoadingTargetResult result;

			private float <elapsed>5__2;

			private float <startAlpha>5__3;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<elapsed>5__2 = 0f;
					<startAlpha>5__3 = 1f;
					if (result.IsRaw && (Object)(object)result.RawImage != (Object)null)
					{
						<startAlpha>5__3 = ((Graphic)result.RawImage).canvasRenderer.GetAlpha();
					}
					else if ((Object)(object)result.Image != (Object)null)
					{
						<startAlpha>5__3 = ((Graphic)result.Image).canvasRenderer.GetAlpha();
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__2 < 0.6f)
				{
					<elapsed>5__2 += Time.unscaledDeltaTime;
					float num = Mathf.Clamp01(<elapsed>5__2 / 0.6f);
					float a = Mathf.Lerp(<startAlpha>5__3, 0f, num);
					TryApplyAlpha(result, a);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				ClearLoadingTarget(result);
				LoadingArtSessionActive = false;
				return false;
			}

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

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

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

			private object <>2__current;

			public string trigger;

			private float <deadlineSearch>5__2;

			private string <chosenLoadingArtPath>5__3;

			private int <scanCount>5__4;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 3u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<chosenLoadingArtPath>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Expected O, but got Unknown
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Expected O, but got Unknown
				//IL_024b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0255: Expected O, but got Unknown
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						goto end_IL_0000;
					case 0:
						<>1__state = -1;
						if (WatcherRunning)
						{
							result = false;
						}
						else
						{
							WatcherRunning = true;
							<>1__state = -3;
							<>2__current = (object)new WaitForSecondsRealtime(0f);
							<>1__state = 1;
							result = true;
						}
						goto end_IL_0000;
					case 1:
					{
						<>1__state = -3;
						<deadlineSearch>5__2 = Time.realtimeSinceStartup + 2400f;
						LoadingTargetResult loadingTargetResult = default(LoadingTargetResult);
						<chosenLoadingArtPath>5__3 = null;
						<scanCount>5__4 = 0;
						break;
					}
					case 2:
						<>1__state = -3;
						break;
					case 3:
						<>1__state = -3;
						break;
					case 4:
						<>1__state = -3;
						break;
					}
					if (Time.realtimeSinceStartup < <deadlineSearch>5__2 && !MMOHeimMainMenuPlugin.TryGetLocalPlayerPresentPlain())
					{
						if (MMOHeimMainMenuPlugin.MainMenuActive)
						{
							<>2__current = (object)new WaitForSecondsRealtime(0.5f);
							<>1__state = 2;
							result = true;
						}
						else
						{
							if (<chosenLoadingArtPath>5__3 == null)
							{
								<chosenLoadingArtPath>5__3 = MMOHeimMainMenuPlugin.GetRandomLoadingArtPath();
							}
							string text = <chosenLoadingArtPath>5__3;
							if (string.IsNullOrEmpty(text) || !File.Exists(text))
							{
								<>2__current = (object)new WaitForSecondsRealtime(0.5f);
								<>1__state = 3;
								result = true;
							}
							else
							{
								Sprite val = SpriteFromFile(text);
								if (!((Object)(object)val != (Object)null))
								{
									goto IL_0245;
								}
								<scanCount>5__4++;
								Stopwatch stopwatch = Stopwatch.StartNew();
								LoadingTargetResult loadingTargetResult2 = FindBestConnectedWorldLoadingTarget();
								stopwatch.Stop();
								LogLoading($"Loading UI scan #{<scanCount>5__4} ({trigger}): {stopwatch.ElapsedMilliseconds} ms, valid={loadingTargetResult2.IsValid}, score={loadingTargetResult2.Score}.");
								if (!loadingTargetResult2.IsValid || !ApplyLoadingTargetResult(loadingTargetResult2, val))
								{
									Object.Destroy((Object)(object)val);
									goto IL_0245;
								}
								LoadingTargetResult loadingTargetResult = loadingTargetResult2;
								LoadingArtSessionActive = true;
								LogLoading("Loading art applied (" + trigger + "): " + loadingTargetResult2.ObjectName + " @ " + loadingTargetResult2.Path + ".");
								StartForceKeep(loadingTargetResult2, val);
								StartCleanup(loadingTargetResult);
								result = false;
								<>m__Finally1();
							}
						}
					}
					else
					{
						if (<scanCount>5__4 == 0)
						{
							LogLoading("Loading watcher ended without UI scan (" + trigger + "): player spawned or timed out.");
						}
						<chosenLoadingArtPath>5__3 = null;
						<>m__Finally1();
						result = false;
					}
					goto end_IL_0000;
					IL_0245:
					<>2__current = (object)new WaitForSecondsRealtime(0.5f);
					<>1__state = 4;
					result = true;
					end_IL_0000:;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				WatcherRunning = false;
				if (_watcherCoroutine != null)
				{
					_watcherCoroutine = null;
				}
			}

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

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

			private object <>2__current;

			public LoadingTargetResult result;

			private float <deadline>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<deadline>5__2 = Time.realtimeSinceStartup + 2400f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!MMOHeimMainMenuPlugin.TryGetLocalPlayerPresentPlain() && Time.realtimeSinceStartup < <deadline>5__2)
				{
					MMOHeimMainMenuPlugin.IsWorldFullyLoaded();
					<>2__current = (object)new WaitForSecondsRealtime(0.5f);
					<>1__state = 1;
					return true;
				}
				MMOHeimMainMenuPlugin.IsWorldFullyLoaded();
				FadeOutAndClearLoadingTarget(result);
				_cleanupCoroutine = null;
				return false;
			}

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

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

		private const float PostSceneDelaySeconds = 0f;

		private const float SearchIntervalSeconds = 0.5f;

		private const float MaxLoadWaitSeconds = 2400f;

		private const float MaintainArtIntervalSeconds = 2f;

		private const int MinimumValidScore = 300;

		private const float LoadingFadeOutSeconds = 0.6f;

		private static Coroutine? _cleanupCoroutine;

		private static Coroutine? _forceCoroutine;

		private static Coroutine? _watcherCoroutine;

		internal static volatile bool WatcherRunning;

		internal static volatile bool LoadingArtSessionActive;

		internal static void ResetForMainMenu()
		{
			StopAllWatchers("main menu reset");
			LoadingArtSessionActive = false;
		}

		internal static void StopAllWatchers(string reason)
		{
			if ((Object)(object)MMOHeimMainMenuPlugin.Instance == (Object)null)
			{
				WatcherRunning = false;
				_watcherCoroutine = null;
				_forceCoroutine = null;
				_cleanupCoroutine = null;
				return;
			}
			if (_watcherCoroutine != null)
			{
				((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_watcherCoroutine);
				_watcherCoroutine = null;
			}
			if (_forceCoroutine != null)
			{
				((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_forceCoroutine);
				_forceCoroutine = null;
			}
			if (_cleanupCoroutine != null)
			{
				((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_cleanupCoroutine);
				_cleanupCoroutine = null;
			}
			if (WatcherRunning || LoadingArtSessionActive)
			{
				LogLoading("Loading watcher stopped (" + reason + ").");
			}
			WatcherRunning = false;
			LoadingArtSessionActive = false;
		}

		internal static void TryStartLoadingScreenWatcher(string trigger)
		{
			if (!MMOHeimMainMenuPlugin.EnableCustomLoadingScreens || (Object)(object)MMOHeimMainMenuPlugin.Instance == (Object)null)
			{
				LogLoading("Loading watcher skipped (" + trigger + "): custom loading screens disabled or plugin missing.");
				return;
			}
			if (MMOHeimMainMenuPlugin.MainMenuActive)
			{
				LogLoading("Loading watcher deferred (" + trigger + "): still on Fejd main menu (world select / UI).");
				return;
			}
			if (WatcherRunning || LoadingArtSessionActive)
			{
				LogLoading("Loading watcher skipped (" + trigger + "): already running.");
				return;
			}
			LogLoading("Loading watcher started (" + trigger + ").");
			_watcherCoroutine = ((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StartCoroutine(WaitForConnectedWorldLoadAndReplaceCoroutine(trigger));
		}

		private static void LogLoading(string message)
		{
			MMOHeimMainMenuPlugin.LogInfo(message);
		}

		[IteratorStateMachine(typeof(<WaitForConnectedWorldLoadAndReplaceCoroutine>d__16))]
		internal static IEnumerator WaitForConnectedWorldLoadAndReplaceCoroutine(string trigger)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForConnectedWorldLoadAndReplaceCoroutine>d__16(0)
			{
				trigger = trigger
			};
		}

		private static void StartCleanup(LoadingTargetResult result)
		{
			if (!((Object)(object)MMOHeimMainMenuPlugin.Instance == (Object)null) && result.IsValid)
			{
				if (_cleanupCoroutine != null)
				{
					((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_cleanupCoroutine);
					_cleanupCoroutine = null;
				}
				_cleanupCoroutine = ((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StartCoroutine(WaitUntilWorldThenClear(result));
			}
		}

		[IteratorStateMachine(typeof(<WaitUntilWorldThenClear>d__18))]
		private static IEnumerator WaitUntilWorldThenClear(LoadingTargetResult result)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitUntilWorldThenClear>d__18(0)
			{
				result = result
			};
		}

		private static void StartForceKeep(LoadingTargetResult result, Sprite sprite)
		{
			if (!((Object)(object)MMOHeimMainMenuPlugin.Instance == (Object)null) && result.IsValid && !((Object)(object)sprite == (Object)null))
			{
				if (_forceCoroutine != null)
				{
					((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_forceCoroutine);
					_forceCoroutine = null;
				}
				_forceCoroutine = ((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StartCoroutine(ForceKeepCoroutine(result, sprite));
			}
		}

		[IteratorStateMachine(typeof(<ForceKeepCoroutine>d__20))]
		private static IEnumerator ForceKeepCoroutine(LoadingTargetResult result, Sprite sprite)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ForceKeepCoroutine>d__20(0)
			{
				result = result,
				sprite = sprite
			};
		}

		private static Sprite? SpriteFromFile(string absolutePath)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				byte[] data = File.ReadAllBytes(absolutePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!TextureDecode.LoadImage(val, data, markNonReadable: false))
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				val.Apply(true, false);
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch
			{
				return null;
			}
		}

		private static void FadeOutAndClearLoadingTarget(LoadingTargetResult result)
		{
			if (!result.IsValid || (Object)(object)MMOHeimMainMenuPlugin.Instance == (Object)null)
			{
				ClearLoadingTarget(result);
				LoadingArtSessionActive = false;
				return;
			}
			if (_cleanupCoroutine != null)
			{
				((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StopCoroutine(_cleanupCoroutine);
				_cleanupCoroutine = null;
			}
			IEnumerator enumerator = LoadingFadeCoroutine(result);
			((MonoBehaviour)MMOHeimMainMenuPlugin.Instance).StartCoroutine(enumerator);
		}

		[IteratorStateMachine(typeof(<LoadingFadeCoroutine>d__23))]
		private static IEnumerator LoadingFadeCoroutine(LoadingTargetResult result)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadingFadeCoroutine>d__23(0)
			{
				result = result
			};
		}

		private static void TryApplyAlpha(LoadingTargetResult result, float a)
		{
			//IL_0041: 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)
			if (result.IsValid)
			{
				Color color = default(Color);
				((Color)(ref color))..ctor(1f, 1f, 1f, Mathf.Clamp01(a));
				if (result.IsRaw && (Object)(object)result.RawImage != (Object)null)
				{
					((Graphic)result.RawImage).color = color;
					((Graphic)result.RawImage).SetAllDirty();
				}
				else if (!result.IsRaw && (Object)(object)result.Image != (Object)null)
				{
					((Graphic)result.Image).color = color;
					((Graphic)result.Image).SetAllDirty();
				}
			}
		}

		internal static LoadingTargetResult FindBestConnectedWorldLoadingTarget()
		{
			LoadingTargetResult loadingTargetResult = default(LoadingTargetResult);
			loadingTargetResult.IsValid = false;
			loadingTargetResult.IsRaw = false;
			loadingTargetResult.Image = null;
			loadingTargetResult.RawImage = null;
			loadingTargetResult.Score = int.MinValue;
			loadingTargetResult.Path = string.Empty;
			loadingTargetResult.ObjectName = string.Empty;
			LoadingTargetResult result = loadingTargetResult;
			Image[] array = Resources.FindObjectsOfTypeAll<Image>();
			foreach (Image val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
				{
					int num = CalculateConnectedWorldLoadingImageScore(val);
					if (num > result.Score)
					{
						result.IsValid = num >= 300;
						result.IsRaw = false;
						result.Image = val;
						result.RawImage = null;
						result.Score = num;
						result.Path = GetHierarchyPath(((Component)val).transform);
						result.ObjectName = ((Object)((Component)val).gameObject).name;
					}
				}
			}
			RawImage[] array2 = Resources.FindObjectsOfTypeAll<RawImage>();
			foreach (RawImage val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					int num2 = CalculateConnectedWorldLoadingRawImageScore(val2);
					if (num2 > result.Score)
					{
						result.IsValid = num2 >= 300;
						result.IsRaw = true;
						result.Image = null;
						result.RawImage = val2;
						result.Score = num2;
						result.Path = GetHierarchyPath(((Component)val2).transform);
						result.ObjectName = ((Object)((Component)val2).gameObject).name;
					}
				}
			}
			return result;
		}

		private static bool ApplyLoadingTargetResult(LoadingTargetResult result, Sprite customSprite)
		{
			if (!result.IsValid || (Object)(object)customSprite == (Object)null)
			{
				return false;
			}
			if (result.IsRaw)
			{
				if ((Object)(object)result.RawImage == (Object)null)
				{
					return false;
				}
				ApplyLoadingRawImage(result.RawImage, customSprite);
			}
			else
			{
				if ((Object)(object)result.Image == (Object)null)
				{
					return false;
				}
				ApplyLoadingImage(result.Image, customSprite);
			}
			return true;
		}

		private static void ApplyLoadingImage(Image target, Sprite customSprite)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			target.sprite = customSprite;
			target.overrideSprite = customSprite;
			((Behaviour)target).enabled = true;
			target.preserveAspect = false;
			target.type = (Type)0;
			((Graphic)target).material = null;
			((Graphic)target).color = Color.white;
			StretchToFullscreen(((Graphic)target).rectTransform);
			((Graphic)target).SetAllDirty();
		}

		private static void ApplyLoadingRawImage(RawImage target, Sprite customSprite)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			target.texture = (Texture)(object)customSprite.texture;
			((Behaviour)target).enabled = true;
			((Graphic)target).material = null;
			((Graphic)target).color = Color.white;
			StretchToFullscreen(((Graphic)target).rectTransform);
			((Graphic)target).SetAllDirty();
		}

		private static void ClearLoadingTarget(LoadingTargetResult result)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (result.IsValid)
			{
				if (result.IsRaw && (Object)(object)result.RawImage != (Object)null && (Object)(object)((Component)result.RawImage).gameObject != (Object)null)
				{
					result.RawImage.texture = null;
					((Graphic)result.RawImage).color = new Color(1f, 1f, 1f, 0f);
					((Behaviour)result.RawImage).enabled = false;
					((Graphic)result.RawImage).SetAllDirty();
				}
				else if (!result.IsRaw && (Object)(object)result.Image != (Object)null && (Object)(object)((Component)result.Image).gameObject != (Object)null)
				{
					result.Image.sprite = null;
					result.Image.overrideSprite = null;
					((Graphic)result.Image).color = new Color(1f, 1f, 1f, 0f);
					((Behaviour)result.Image).enabled = false;
					((Graphic)result.Image).SetAllDirty();
				}
			}
		}

		private static bool Approximately(float a, float b)
		{
			return Mathf.Abs(a - b) <= 0.001f;
		}

		internal static bool IsFullscreenLike(RectTransform rt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0097: 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)
			if ((Object)(object)rt == (Object)null)
			{
				return false;
			}
			bool num = Approximately(rt.anchorMin.x, 0f) && Approximately(rt.anchorMin.y, 0f) && Approximately(rt.anchorMax.x, 1f) && Approximately(rt.anchorMax.y, 1f);
			bool flag = Approximately(rt.offsetMin.x, 0f) && Approximately(rt.offsetMin.y, 0f) && Approximately(rt.offsetMax.x, 0f) && Approximately(rt.offsetMax.y, 0f);
			return num && flag;
		}

		internal static string GetHierarchyPath(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "<null>";
			}
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				list.Insert(0, ((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", list.ToArray());
		}

		internal static int CalculateConnectedWorldLoadingImageScore(Image img)
		{
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((img != null) ? ((Component)img).gameObject : null) == (Object)null)
			{
				return int.MinValue;
			}
			string text = ((Object)((Component)img).gameObject).name ?? string.Empty;
			text = text.ToLowerInvariant();
			string text2 = GetHierarchyPath(((Component)img).transform).ToLowerInvariant();
			string text3 = (((Object)(object)img.sprite != (Object)null) ? (((Object)img.sprite).name ?? string.Empty).ToLowerInvariant() : string.Empty);
			if (!text2.Contains("loadinggui"))
			{
				return int.MinValue;
			}
			if (text2.Contains("popupblockingbackground") || text2.Contains("unifiedpopup") || text2.Contains("achievementpopup") || text2.Contains("achievementui") || text2.Contains("editguild") || text2.Contains("createguild") || text2.Contains("searchguild") || text2.Contains("guildmanagementui") || text2.Contains("applicationsui") || text2.Contains("noguild") || text2.Contains("discord") || text2.Contains("_console(clone)") || text2.Contains("/_console") || text2.Contains("logoutput") || text2.Contains("serveroptions") || text2.Contains("connectionfailed") || text2.Contains("managesavesmenu") || text2.Contains("removecharacterdialog") || text2.Contains("pleasewait"))
			{
				return int.MinValue;
			}
			if (!text.Contains("crosshair") && !text.Contains("healthicon") && !text.Contains("foodicon") && !text.Contains("windicon") && !text.Contains("mounticon") && !text.Contains("player_marker") && !text.Contains("ship_marker") && !text.Contains("wind_marker"))
			{
				switch (text)
				{
				case "backgroundback":
				case "buttonclose":
				case "button":
				case "border":
				case "bkg":
				case "bar":
				case "darken":
				case "handle":
				case "separator":
					break;
				default:
				{
					if (text2.Contains("/enemyhud/") || text2.Contains("/inventory_screen/") || text2.Contains("/statuseffects/") || text2.Contains("/keyhints/") || text2.Contains("/buildhud/") || text2.Contains("/shiphud/controls/") || text2.Contains("/crosshair/") || text2.Contains("/guardianpower/"))
					{
						return int.MinValue;
					}
					int num = 0;
					if (text == "screen")
					{
						num += 5000;
					}
					if (text2.EndsWith("/hud/screen"))
					{
						num += 5000;
					}
					if (text2.Contains("/hud/screen"))
					{
						num += 3000;
					}
					if (text2.Contains("loadinggui"))
					{
						num += 300;
					}
					if (text2.Contains("pixelfix"))
					{
						num += 40;
					}
					if (text2.Contains("/hud/"))
					{
						num += 150;
					}
					if (text2.Contains("/ingamegui/"))
					{
						num += 50;
					}
					if (text == "background")
					{
						num += 180;
					}
					if (text.Contains("background"))
					{
						num += 120;
					}
					if (text3.Contains("background"))
					{
						num += 60;
					}
					if (text.Contains("image"))
					{
						num += 20;
					}
					if (((Behaviour)img).enabled)
					{
						num += 20;
					}
					if (((Component)img).gameObject.activeInHierarchy)
					{
						num += 60;
					}
					if ((Object)(object)((Graphic)img).canvasRenderer != (Object)null && ((Graphic)img).canvasRenderer.GetAlpha() > 0.01f)
					{
						num += 40;
					}
					RectTransform rectTransform = ((Graphic)img).rectTransform;
					if ((Object)(object)rectTransform != (Object)null)
					{
						Rect rect = rectTransform.rect;
						float num2 = Mathf.Abs(((Rect)(ref rect)).width);
						rect = rectTransform.rect;
						float num3 = Mathf.Abs(((Rect)(ref rect)).height);
						float num4 = num2 * num3;
						if (num4 < 200000f)
						{
							return int.MinValue;
						}
						if (num4 > 300000f)
						{
							num += 60;
						}
						if (num4 > 500000f)
						{
							num += 120;
						}
						if (num4 > 1000000f)
						{
							num += 220;
						}
						if (num4 > 1800000f)
						{
							num += 320;
						}
						if (num2 >= (float)Screen.width * 0.7f)
						{
							num += 80;
						}
						if (num3 >= (float)Screen.height * 0.7f)
						{
							num += 80;
						}
						if (num2 >= (float)Screen.width * 0.9f)
						{
							num += 100;
						}
						if (num3 >= (float)Screen.height * 0.9f)
						{
							num += 100;
						}
						if (IsFullscreenLike(rectTransform))
						{
							num += 400;
						}
					}
					return num;
				}
				}
			}
			return int.MinValue;
		}

		internal static int CalculateConnectedWorldLoadingRawImageScore(RawImage raw)
		{
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((raw != null) ? ((Component)raw).gameObject : null) == (Object)null)
			{
				return int.MinValue;
			}
			string text = (((Object)((Component)raw).gameObject).name ?? string.Empty).ToLowerInvariant();
			string text2 = GetHierarchyPath(((Component)raw).transform).ToLowerInvariant();
			if (!text2.Contains("loadinggui"))
			{
				return int.MinValue;
			}
			if (text2.Contains("popupblockingbackground") || text2.Contains("unifiedpopup") || text2.Contains("achievementpopup") || text2.Contains("achievementui") || text2.Contains("editguild") || text2.Contains("createguild") || text2.Contains("searchguild") || text2.Contains("guildmanagementui") || text2.Contains("applicationsui") || text2.Contains("noguild") || text2.Contains("discord") || text2.Contains("_console(clone)") || text2.Contains("/_console") || text2.Contains("logoutput") || text2.Contains("serveroptions") || text2.Contains("connectionfailed") || text2.Contains("managesavesmenu") || text2.Contains("removecharacterdialog") || text2.Contains("pleasewait"))
			{
				return int.MinValue;
			}
			if (text2.Contains("/enemyhud/") || text2.Contains("/inventory_screen/") || text2.Contains("/statuseffects/") || text2.Contains("/keyhints/") || text2.Contains("/buildhud/") || text2.Contains("/shiphud/controls/") || text2.Contains("/crosshair/") || text2.Contains("/guardianpower/"))
			{
				return int.MinValue;
			}
			int num = 0;
			if (text == "screen")
			{
				num += 5000;
			}
			if (text2.EndsWith("/hud/screen"))
			{
				num += 5000;
			}
			if (text2.Contains("/hud/screen"))
			{
				num += 3000;
			}
			if (text2.Contains("loadinggui"))
			{
				num += 300;
			}
			if (text2.Contains("pixelfix"))
			{
				num += 40;
			}
			if (text2.Contains("/hud/"))
			{
				num += 150;
			}
			if (text == "background")
			{
				num += 180;
			}
			if (text.Contains("background"))
			{
				num += 120;
			}
			if (text.Contains("image"))
			{
				num += 20;
			}
			if (((Behaviour)raw).enabled)
			{
				num += 20;
			}
			if (((Component)raw).gameObject.activeInHierarchy)
			{
				num += 60;
			}
			RectTransform rectTransform = ((Graphic)raw).rectTransform;
			if ((Object)(object)rectTransform != (Object)null)
			{
				Rect rect = rectTransform.rect;
				float num2 = Mathf.Abs(((Rect)(ref rect)).width);
				rect = rectTransform.rect;
				float num3 = Mathf.Abs(((Rect)(ref rect)).height);
				float num4 = num2 * num3;
				if (num4 < 200000f)
				{
					return int.MinValue;
				}
				if (num4 > 300000f)
				{
					num += 60;
				}
				if (num4 > 500000f)
				{
					num += 120;
				}
				if (num4 > 1000000f)
				{
					num += 220;
				}
				if (num4 > 1800000f)
				{
					num += 320;
				}
				if (num2 >= (float)Screen.width * 0.7f)
				{
					num += 80;
				}
				if (num3 >= (float)Screen.height * 0.7f)
				{
					num += 80;
				}
				if (num2 >= (float)Screen.width * 0.9f)
				{
					num += 100;
				}
				if (num3 >= (float)Screen.height * 0.9f)
				{
					num += 100;
				}
				if (IsFullscreenLike(rectTransform))
				{
					num += 400;
				}
			}
			return num;
		}

		internal static void StretchToFullscreen(RectTransform rt)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rt == (Object)null))
			{
				rt.anchorMin = Vector2.zero;
				rt.anchorMax = Vector2.one;
				rt.pivot = new Vector2(0.5f, 0.5f);
				rt.offsetMin = Vector2.zero;
				rt.offsetMax = Vector2.zero;
				rt.anchoredPosition = Vector2.zero;
				((Transform)rt).localScale = Vector3.one;
				((Transform)rt).localRotation = Quaternion.identity;
			}
		}
	}
	internal static class MenuAtmosphere
	{
		private enum ApplyMode
		{
			None,
			EnvMan,
			StartSceneFallback
		}

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

			private object <>2__current;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!IsFeatureEnabled())
					{
						return false;
					}
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 180 && MMOHeimMainMenuPlugin.MainMenuActive)
				{
					if (TryApplyEnvMan())
					{
						return false;
					}
					if (<i>5__2 >= 2 && TryApplyStartSceneFallback(logApply: true))
					{
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (MMOHeimMainMenuPlugin.MainMenuActive && _mode == ApplyMode.None)
				{
					LogAtmosphere("Menu atmosphere: timed out waiting for EnvMan; start-scene night fallback was not applied.");
				}
				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();
			}
		}

		internal const float DefaultNightTimeFraction = 0.875f;

		internal const float MaintainIntervalSeconds = 0.25f;

		private const float FallbackSunAngle = 45f;

		private static readonly Color FallbackFogColor = new Color(0.047f, 0.165f, 0.196f, 1f);

		private static readonly Color FallbackAmbientLight = new Color(0.191f, 0.269f, 0.36f, 1f);

		private static readonly Color FallbackSunColor = new Color(0.337f, 0.729f, 0.714f, 1f);

		private const float FallbackFogDensity = 0.08f;

		private const float FallbackSunIntensity = 0.05f;

		private static ConfigEntry<bool>? _enabled;

		private static ConfigEntry<string>? _environment;

		private static ConfigEntry<float>? _nightTimeFraction;

		private static ApplyMode _mode;

		private static string? _appliedEnvironment;

		private static bool _fallbackSnapshotTaken;

		private static bool _fallbackLoggedApply;

		private static bool _envManNightPinned;

		private static bool _envManHadDebugTimeOfDay;

		private static float _envManSavedDebugTime;

		private static bool _fallbackFog;

		private static Color _fallbackFogColor;

		private static float _fallbackFogDensity;

		private static AmbientMode _fallbackAmbientMode;

		private static Color _fallbackAmbientLight;

		private static float _fallbackSunIntensity;

		private static Color _fallbackSunColor;

		private static Quaternion _fallbackSunRotation;

		private static bool _fallbackSunStored;

		private static Light? _cachedDirectionalLight;

		private static Quaternion _cachedNightRotation;

		private static float _cachedNightFraction = 0.875f;

		private static bool _lightResolveAttempted;

		internal static void BindConfig(ConfigFile config)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			_enabled = config.Bind<bool>("Menu Atmosphere", "Enabled", true, "Force deep night and fog on the login / main menu (start.unity). Cleared when joining a world.");
			_environment = config.Bind<string>("Menu Atmosphere", "Environment", string.Empty, "Optional Valheim environment id for EnvMan when present. Leave empty for night-only menu atmosphere (recommended).");
			_nightTimeFraction = config.Bind<float>("Menu Atmosphere", "NightTimeFraction", 0.875f, new ConfigDescription("Pinned day fraction while on the main menu (0-1). 0.875 is deep night.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		}

		internal static bool IsFeatureEnabled()
		{
			if (MMOHeimMainMenuPlugin.ModEnabled != null && MMOHeimMainMenuPlugin.ModEnabled.Value && _enabled != null)
			{
				return _enabled.Value;
			}
			return false;
		}

		internal static void ResetForMenuSession()
		{
			//IL_0044: 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)
			_mode = ApplyMode.None;
			_appliedEnvironment = null;
			_fallbackSnapshotTaken = false;
			_fallbackSunStored = false;
			_fallbackLoggedApply = false;
			_envManNightPinned = false;
			_cachedDirectionalLight = null;
			_lightResolveAttempted = false;
			_cachedNightFraction = GetNightFraction();
			_cachedNightRotation = ComputeNightRotation(_cachedNightFraction, 45f);
		}

		internal static bool WantsPeriodicMaintain()
		{
			if (!IsFeatureEnabled())
			{
				return false;
			}
			return !string.IsNullOrEmpty((_environment?.Value ?? string.Empty).Trim());
		}

		[IteratorStateMachine(typeof(<ApplyWhenReady>d__36))]
		internal static IEnumerator ApplyWhenReady()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyWhenReady>d__36(0);
		}

		internal static void Apply()
		{
			if (IsFeatureEnabled() && !TryApplyEnvMan())
			{
				TryApplyStartSceneFallback(logApply: true);
			}
		}

		internal static void Clear()
		{
			ClearEnvMan();
			ClearEnvManNightPin();
			ClearStartSceneFallback();
			_mode = ApplyMode.None;
			_appliedEnvironment = null;
			_fallbackLoggedApply = false;
			_cachedDirectionalLight = null;
			_lightResolveAttempted = false;
		}

		internal static void MaintainAppliedState()
		{
			if (!MMOHeimMainMenuPlugin.MainMenuActive || !IsFeatureEnabled())
			{
				return;
			}
			switch (_mode)
			{
			case ApplyMode.EnvMan:
				if (!IsEnvManStillApplied())
				{
					TryApplyEnvMan();
				}
				break;
			case ApplyMode.StartSceneFallback:
				EnsureEnvManNightPin();
				break;
			}
		}

		private static bool TryApplyEnvMan()
		{
			EnvMan val = ResolveEnvMan();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			string text = (_environment?.Value ?? string.Empty).Trim();
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			ClearStartSceneFallback(restoreSnapshot: false);
			val.SetForceEnvironment(text);
			val.m_debugTimeOfDay = true;
			val.m_debugTime = GetNightFraction();
			_mode = ApplyMode.EnvMan;
			_appliedEnvironment = text;
			LogAtmosphere($"Menu atmosphere applied via EnvMan: {text}, night fraction {val.m_debugTime:0.###}.");
			return true;
		}

		private static bool TryApplyStartSceneFallback(bool logApply)
		{
			if (_mode == ApplyMode.EnvMan)
			{
				return true;
			}
			if (!EnsureDirectionalLightCached())
			{
				return false;
			}
			CaptureFallbackSnapshot();
			ApplyStartSceneFallbackValuesOnly();
			EnsureEnvManNightPin();
			_mode = ApplyMode.StartSceneFallback;
			_appliedEnvironment = "night-fallback";
			if (logApply && !_fallbackLoggedApply)
			{
				_fallbackLoggedApply = true;
				LogAtmosphere($"Menu atmosphere applied via start-scene fallback (night, fog density {0.08f:0.###}, fraction {GetNightFraction():0.###}).");
			}
			return true;
		}

		private static void ApplyStartSceneFallbackValuesOnly()
		{
			//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_0024: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			_cachedNightFraction = GetNightFraction();
			_cachedNightRotation = ComputeNightRotation(_cachedNightFraction, 45f);
			RenderSettings.fog = true;
			RenderSettings.fogColor = FallbackFogColor;
			RenderSettings.fogDensity = 0.08f;
			RenderSettings.ambientMode = (AmbientMode)3;
			RenderSettings.ambientLight = FallbackAmbientLight;
			if ((Object)(object)_cachedDirectionalLight != (Object)null)
			{
				((Component)_cachedDirectionalLight).transform.rotation = _cachedNightRotation;
				_cachedDirectionalLight.intensity = 0.05f;
				_cachedDirectionalLight.color = FallbackSunColor;
			}
		}

		private static bool EnsureDirectionalLightCached()
		{
			if ((Object)(object)_cachedDirectionalLight != (Object)null)
			{
				return true;
			}
			if (_lightResolveAttempted)
			{
				return false;
			}
			_lightResolveAttempted = true;
			_cachedDirectionalLight = ResolveMenuDirectionalLightOnce();
			return (Object)(object)_cachedDirectionalLight != (Object)null;
		}

		private static Light? ResolveMenuDirectionalLightOnce()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			GameObject val = GameObject.Find("Directional light");
			if ((Object)(object)val == (Object)null)
			{
				val = GameObject.Find("Directional Light");
			}
			if ((Object)(object)val != (Object)null)
			{
				Light component = val.GetComponent<Light>();
				if ((Object)(object)component != (Object)null && (int)component.type == 1)
				{
					return component;
				}
			}
			Light sun = RenderSettings.sun;
			if ((Object)(object)sun != (Object)null && (int)sun.type == 1)
			{
				return sun;
			}
			Light[] array = Object.FindObjectsByType<Light>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (Light val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && (int)val2.type == 1)
				{
					return val2;
				}
			}
			return null;
		}

		private static Quaternion ComputeNightRotation(float dayFraction, float sunAngle)
		{
			//IL_0011: 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_002a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(-90f + sunAngle, 0f, 0f) * Quaternion.Euler(0f, -90f, 0f) * Quaternion.Euler(-90f + 360f * dayFraction, 0f, 0f);
		}

		private static void CaptureFallbackSnapshot()
		{
			//IL_0012: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!_fallbackSnapshotTaken)
			{
				_fallbackFog = RenderSettings.fog;
				_fallbackFogColor = RenderSettings.fogColor;
				_fallbackFogDensity = RenderSettings.fogDensity;
				_fallbackAmbientMode = RenderSettings.ambientMode;
				_fallbackAmbientLight = RenderSettings.ambientLight;
				Light cachedDirectionalLight = _cachedDirectionalLight;
				if ((Object)(object)cachedDirectionalLight != (Object)null)
				{
					_fallbackSunStored = true;
					_fallbackSunIntensity = cachedDirectionalLight.intensity;
					_fallbackSunColor = cachedDirectionalLight.color;
					_fallbackSunRotation = ((Component)cachedDirectionalLight).transform.rotation;
				}
				else
				{
					_fallbackSunStored = false;
				}
				_fallbackSnapshotTaken = true;
			}
		}

		private static void ClearEnvMan()
		{
			if (_mode == ApplyMode.EnvMan)
			{
				EnvMan val = ResolveEnvMan();
				if ((Object)(object)val != (Object)null)
				{
					val.SetForceEnvironment(string.Empty);
					val.m_debugTimeOfDay = false;
				}
				LogAtmosphere("Menu atmosphere cleared (EnvMan).");
			}
		}

		private static void EnsureEnvManNightPin()
		{
			EnvMan val = ResolveEnvMan();
			if (!((Object)(object)val == (Object)null))
			{
				if (!_envManNightPinned)
				{
					_envManHadDebugTimeOfDay = val.m_debugTimeOfDay;
					_envManSavedDebugTime = val.m_debugTime;
					_envManNightPinned = true;
				}
				val.m_debugTimeOfDay = true;
				val.m_debugTime = GetNightFraction();
			}
		}

		private static void ClearEnvManNightPin()
		{
			if (_envManNightPinned)
			{
				EnvMan val = ResolveEnvMan();
				if ((Object)(object)val != (Object)null)
				{
					val.m_debugTimeOfDay = _envManHadDebugTimeOfDay;
					val.m_debugTime = _envManSavedDebugTime;
				}
				_envManNightPinned = false;
			}
		}

		private static void ClearStartSceneFallback(bool restoreSnapshot = true)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0074: 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)
			if (_mode != ApplyMode.StartSceneFallback && !_fallbackSnapshotTaken)
			{
				return;
			}
			if (restoreSnapshot && _fallbackSnapshotTaken)
			{
				RenderSettings.fog = _fallbackFog;
				RenderSettings.fogColor = _fallbackFogColor;
				RenderSettings.fogDensity = _fallbackFogDensity;
				RenderSettings.ambientMode = _fallbackAmbientMode;
				RenderSettings.ambientLight = _fallbackAmbientLight;
				if (_fallbackSunStored && (Object)(object)_cachedDirectionalLight != (Object)null)
				{
					_cachedDirectionalLight.intensity = _fallbackSunIntensity;
					_cachedDirectionalLight.color = _fallbackSunColor;
					((Component)_cachedDirectionalLight).transform.rotation = _fallbackSunRotation;
				}
			}
			_fallbackSnapshotTaken = false;
			_fallbackSunStored = false;
			if (_mode == ApplyMode.StartSceneFallback)
			{
				LogAtmosphere("Menu atmosphere cleared (start-scene fallback).");
			}
		}

		private static bool IsEnvManStillApplied()
		{
			EnvMan val = ResolveEnvMan();
			if ((Object)(object)val == (Object)null || _mode != ApplyMode.EnvMan)
			{
				return false;
			}
			if (!val.m_debugTimeOfDay)
			{
				return false;
			}
			string text = _appliedEnvironment ?? _environment?.Value ?? string.Empty;
			EnvSetup currentEnvironment = val.GetCurrentEnvironment();
			if (currentEnvironment != null)
			{
				return currentEnvironment.m_name == text;
			}
			return false;
		}

		private static EnvMan? ResolveEnvMan()
		{
			if ((Object)(object)EnvMan.instance != (Object)null)
			{
				return EnvMan.instance;
			}
			return Object.FindFirstObjectByType<EnvMan>();
		}

		private static float GetNightFraction()
		{
			return _nightTimeFraction?.Value ?? 0.875f;
		}

		private static void LogAtmosphere(string message)
		{
			ManualLogSource? modLog = MMOHeimMainMenuPlugin.ModLog;
			if (modLog != null)
			{
				modLog.LogInfo((object)message);
			}
		}
	}
	internal static class MenuScenery
	{
		[CompilerGenerated]
		private sealed class <ApplyStagingWhenReady>d__53 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public FejdStartup startup;

			private int <attempt>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Expected O, but got Unknown
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						goto end_IL_0000;
					case 0:
						<>1__state = -1;
						<>1__state = -3;
						TakeVanillaSnapshotIfNeeded(startup);
						EnsurePropsVisible();
						ApplyCameraMarkers(startup);
						ApplyPlayerPreview(startup);
						<>2__current = (object)new WaitForSecondsRealtime(0.5f);
						<>1__state = 1;
						result = true;
						goto end_IL_0000;
					case 1:
						<>1__state = -3;
						<attempt>5__2 = 0;
						break;
					case 2:
						<>1__state = -3;
						<attempt>5__2++;
						break;
					}
					if (<attempt>5__2 < 24 && MMOHeimMainMenuPlugin.MainMenuActive)
					{
						if (EnsureClonedFire())
						{
							result = false;
							<>m__Finally1();
						}
						else
						{
							<>2__current = (object)new WaitForSecondsRealtime(0.25f);
							<>1__state = 2;
							result = true;
						}
					}
					else
					{
						if (MMOHeimMainMenuPlugin.MainMenuActive)
						{
							MMOHeimMainMenuPlugin.LogWarn("Menu scenery: MenuFire not found after retries (logout staging).");
						}
						<>m__Finally1();
						result = false;
					}
					end_IL_0000:;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (_stagingCoroutine != null && (Object)(object)_stagingHost == (Object)(object)startup)
				{
					_stagingCoroutine = null;
					_stagingHost = null;
				}
			}

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

		internal static readonly Vector3 CoastalCharacterPosition = new Vector3(-206.2f, 39.5f, 162.3f);

		internal static readonly Vector3 CoastalCharacterRotation = new Vector3(19.6f, -211f, 0f);

		internal static readonly Vector3 CoastalCreditsPosition = new Vector3(-205.3f, 34.5f, 132.1f);

		internal static readonly Vector3 CoastalCreditsRotation = new Vector3(19.6f, -211f, 0f);

		internal static readonly Vector3 CoastalStartMainPosition = new Vector3(-208.54f, 32.35f, 131.45f);

		internal static readonly Vector3 CoastalStartMainRotation = new Vector3(0.72f, -211f, 0f);

		internal static readonly Vector3 CoastalGamePosition = new Vector3(-204.55f, 38.1f, 158.9f);

		internal static readonly Vector3 CoastalGameRotation = new Vector3(-181.447f, -48.532f, -180f);

		internal static readonly Vector3 CoastalSavesPosition = new Vector3(-208.45f, 45.9f, 131.3f);

		internal static readonly Vector3 CoastalSavesRotation = new Vector3(0.72f, -211f, 0f);

		internal static readonly Vector3 CoastalPlayerPosition = new Vector3(-204.51f, 36.55f, 157.6f);

		internal static readonly Vector3 CoastalFirePosition = new Vector3(-203.51f, 36.55f, 158.63f);

		private const float FireLevelRadius = 4f;

		private const float FireSmoothRadius = 8f;

		private const float FireSmoothPower = 2f;

		private const float FirePaintRadius = 3f;

		private const PaintType FirePaintType = 2;

		private const float StagingSettleDelaySeconds = 0.5f;

		private const float FireRetryIntervalSeconds = 0.25f;

		private const int FireRetryMaxAttempts = 24;

		private static ConfigEntry<bool>? _enabled;

		private static ConfigEntry<bool>? _depthOfFieldOnCharacterSelect;

		private static bool _vanillaSnapshotTaken;

		private static Vector3 _vanillaCharacterPosition;

		private static Vector3 _vanillaCreditsPosition;

		private static Vector3 _vanillaGamePosition;

		private static Vector3 _vanillaMainPosition;

		private static Vector3 _vanillaStartPosition;

		private static Vector3 _vanillaSavesPosition;

		private static Vector3 _vanillaCharacterRotation;

		private static Vector3 _vanillaCreditsRotation;

		private static Vector3 _vanillaGameRotation;

		private static Vector3 _vanillaMainRotation;

		private static Vector3 _vanillaStartRotation;

		private static Vector3 _vanillaSavesRotation;

		private static Vector3 _vanillaPlayerPosition;

		private static Vector3 _vanillaPlayerRotation;

		private static GameObject? _clonedFire;

		private static GameObject? _sourceMenuFire;

		private static FejdStartup? _stagingHost;

		private static Coroutine? _stagingCoroutine;

		private static bool _propsActivated;

		private static Behaviour? _cachedDepthOfField;

		private static FieldInfo? _playerInstanceField;

		internal static void BindConfig(ConfigFile config)
		{
			_enabled = config.Bind<bool>("Menu Scenery", "Enabled", true, "Coastal login viewpoint on start.unity (camera markers, ships/rocks, campfire). Cleared when joining a world.");
			_depthOfFieldOnCharacterSelect = config.Bind<bool>("Menu Scenery", "DepthOfFieldOnCharacterSelect", true, "Enable depth-of-field on the main camera during character select and credits.");
		}

		internal static bool IsFeatureEnabled()
		{
			if (MMOHeimMainMenuPlugin.ModEnabled != null && MMOHeimMainMenuPlugin.ModEnabled.Value && _enabled != null)
			{
				return _enabled.Value;
			}
			return false;
		}

		internal static void ResetForMenuSession()
		{
			StopStagingCoroutine();
			DestroyAllMenuFireClones(destroyImmediate: false);
			_propsActivated = false;
			_cachedDepthOfField = null;
			_sourceMenuFire = null;
		}

		internal static void OnSetupGui(FejdStartup startup)
		{
			if (IsFeatureEnabled() && !((Object)(object)startup == (Object)null))
			{
				TakeVanillaSnapshotIfNeeded(startup);
				ApplyStagingImmediate(startup);
			}
		}

		internal static void ScheduleApplyStaging(FejdStartup startup)
		{
			if (IsFeatureEnabled() && !((Object)(object)startup == (Object)null))
			{
				StopStagingCoroutine();
				_stagingHost = startup;
				_stagingCoroutine = ((MonoBehaviour)startup).StartCoroutine(ApplyStagingWhenReady(startup));
			}
		}

		internal static void OnUpdateCamera(FejdStartup startup)
		{
			if (IsFeatureEnabled() && MMOHeimMainMenuPlugin.MainMenuActive && !((Object)(object)startup == (Object)null))
			{
				ApplyCameraMarkers(startup);
				UpdateDepthOfField(startup);
			}
		}

		internal static void OnShowCharacterSelection(FejdStartup startup)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			if (IsFeatureEnabled() && MMOHeimMainMenuPlugin.MainMenuActive && !((Object)(object)startup == (Object)null))
			{
				ApplyPlayerPreview(startup);
				Quaternion rotation = startup.m_cameraMarkerCharacter.rotation;
				float num = ((Quaternion)(ref rotation)).eulerAngles.y - 180f;
				Quaternion rotation2 = Quaternion.Euler(0f, num, 0f);
				startup.m_characterPreviewPoint.rotation = rotation2;
				GameObject playerInstance = GetPlayerInstance(startup);
				if ((Object)(object)playerInstance != (Object)null)
				{
					playerInstance.transform.rotation = rotation2;
				}
			}
		}

		internal static void OnCharacterStartPreview(FejdStartup startup)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			if (IsFeatureEnabled() && MMOHeimMainMenuPlugin.MainMenuActive && !((Object)(object)startup == (Object)null))
			{
				ApplyPlayerPreview(startup);
				Quaternion rotation = startup.m_cameraMarkerCharacter.rotation;
				float num = ((Quaternion)(ref rotation)).eulerAngles.y - 40f;
				Quaternion rotation2 = Quaternion.Euler(0f, num, 0f);
				startup.m_characterPreviewPoint.rotation = rotation2;
				GameObject playerInstance = GetPlayerInstance(startup);
				if ((Object)(object)playerInstance != (Object)null)
				{
					playerInstance.transform.rotation = rotation2;
				}
			}
		}

		internal static void Clear()
		{
			StopStagingCoroutine();
			FejdStartup instance = FejdStartup.instance;
			if (_vanillaSnapshotTaken && (Object)(object)instance != (Object)null)
			{
				RestoreVanillaMarkers(instance);
				RestoreVanillaPlayerPreview(instance);
			}
			DestroyAllMenuFireClones(destroyImmediate: true);
			_propsActivated = false;
			_cachedDepthOfField = null;
			_sourceMenuFire = null;
		}

		[IteratorStateMachine(typeof(<ApplyStagingWhenReady>d__53))]
		private static IEnumerator ApplyStagingWhenReady(FejdStartup startup)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyStagingWhenReady>d__53(0)
			{
				startup = startup
			};
		}

		private static void ApplyStagingImmediate(FejdStartup startup)
		{
			EnsurePropsVisible();
			ApplyCameraMarkers(startup);
			ApplyPlayerPreview(startup);
			EnsureClonedFire();
		}

		private static void TakeVanillaSnapshotIfNeeded(FejdStartup startup)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_005e: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_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_009e: 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_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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00db: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if (!_vanillaSnapshotTaken)
			{
				_vanillaCharacterPosition = startup.m_cameraMarkerCharacter.position;
				_vanillaCreditsPosition = startup.m_cameraMarkerCredits.position;
				_vanillaGamePosition = startup.m_cameraMarkerGame.position;
				_vanillaMainPosition = startup.m_cameraMarkerMain.position;
				_vanillaStartPosition = startup.m_cameraMarkerStart.position;
				_vanillaSavesPosition = startup.m_cameraMarkerSaves.position;
				Quaternion rotation = startup.m_cameraMarkerCharacter.rotation;
				_vanillaCharacterRotation = ((Quaternion)(ref rotation)).eulerAngles;
				rotation = startup.m_cameraMarkerCredits.rotation;
				_vanillaCreditsRotation = ((Quaternion)(ref rotation)).eulerAngles;
				rotation = startup.m_cameraMarkerGame.rotation;
				_vanillaGameRotation = ((Quaternion)(ref rotation)).eulerAngles;
				rotation = startup.m_cameraMarkerMain.rotation;
				_vanillaMainRotation = ((Quaternion)(ref rotation)).eulerAngles;
				rotation = startup.m_cameraMarkerStart.rotation;
				_vanillaStartRotation = ((Quaternion)(ref rotation)).eulerAngles;
				rotation = startup.m_cameraMarkerSaves.rotation;
				_vanillaSavesRotation = ((Quaternion)(ref rotation)).eulerAngles;
				_vanillaPlayerPosition = startup.m_characterPreviewPoint.position;
				rotation = startup.m_characterPreviewPoint.rotation;
				_vanillaPlayerRotation = ((Quaternion)(ref rotation)).eulerAngles;
				_vanillaSnapshotTaken = true;
			}
		}

		private static void EnsurePropsVisible()
		{
			if (_propsActivated)
			{
				return;
			}
			try
			{
				GameObject val = GameObject.Find("Static");
				if ((Object)(object)val == (Object)null)
				{
					MMOHeimMainMenuPlugin.LogWarn("Menu scenery: Static root not found.");
					return;
				}
				Transform val2 = FindChildTransform(val.transform, "props");
				if ((Object)(object)val2 == (Object)null)
				{
					MMOHeimMainMenuPlugin.LogWarn("Menu scenery: props not found under Static.");
					return;
				}
				((Component)val2).gameObject.SetActive(true);
				Transform val3 = FindChildTransform(val2, "Rocks");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(true);
				}
				Transform val4 = FindChildTransform(val2, "ships");
				if ((Object)(object)val4 != (Object)null)
				{
					((Component)val4).gameObject.SetActive(true);
				}
				_propsActivated = true;
			}
			catch (Exception ex)
			{
				MMOHeimMainMenuPlugin.LogWarn("Menu scenery: failed to enable props: " + ex.Message);
			}
		}

		private static GameObject? ResolveSourceMenuFire()
		{
			if ((Object)(object)_sourceMenuFire != (Object)null)
			{
				return _sourceMenuFire;
			}
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject val in array)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == "MenuFire")
				{
					_sourceMenuFire = val;
					return val;
				}
			}
			return null;
		}

		private static bool EnsureClonedFire()
		{
			//IL_0022: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!MMOHeimMainMenuPlugin.MainMenuActive)
			{
				return false;
			}
			if ((Object)(object)_clonedFire != (Object)null)
			{
				_clonedFire.transform.position = CoastalFirePosition;
				return true;
			}
			try
			{
				GameObject val = ResolveSourceMenuFire();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				_clonedFire = Object.Instantiate<GameObject>(val, CoastalFirePosition, Quaternion.identity);
				TerrainModifier obj = _clonedFire.AddComponent<TerrainModifier>();
				obj.m_level = true;
				obj.m_levelRadius = 4f;
				obj.m_smooth = true;
				obj.m_smoothRadius = 8f;
				obj.m_smoothPower = 2f;
				obj.m_paintCleared = true;
				obj.m_paintType = (PaintType)2;
				obj.m_paintRadius = 3f;
				return true;
			}
			catch (Exception ex)
			{
				MMOHeimMainMenuPlugin.LogWarn("Menu scenery: failed to clone MenuFire: " + ex.Message);
				return false;
			}
		}

		private static void StopStagingCoroutine()
		{
			if ((Object)(object)_stagingHost != (Object)null && _stagingCoroutine != null)
			{
				try
				{
					((MonoBehaviour)_stagingHost).StopCoroutine(_stagingCoroutine);
				}
				catch (Exception ex)
				{
					MMOHeimMainMenuPlugin.LogWarn("Menu scenery: could not stop staging coroutine: " + ex.Message);
				}
			}
			_stagingCoroutine = null;
			_stagingHost = null;
		}

		private static void DestroyAllMenuFireClones(bool destroyImmediate)
		{
			if ((Object)(object)_clonedFire != (Object)null)
			{
				DestroyFireObject(_clonedFire, destroyImmediate);
				_clonedFire = null;
			}
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject val in array)
			{
				if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "MenuFire(Clone)") && IsCoastalMenuFireClone(val))
				{
					DestroyFireObject(val, destroyImmediate);
				}
			}
		}

		private static bool IsCoastalMenuFireClone(GameObject go)
		{
			//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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(go.transform.position - CoastalFirePosition) < 4f;
		}

		private static void DestroyFireObject(GameObject go, bool destroyImmediate)
		{
			if (!((Object)(object)go == (Object)null))
			{
				if (destroyImmediate)
				{
					Object.DestroyImmediate((Object)(object)go);
				}
				else
				{
					Object.Destroy((Object)(object)go);
				}
			}
		}

		private static void ApplyCameraMarkers(FejdStartup startup)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			startup.m_cameraMarkerCharacter.position = CoastalCharacterPosition;
			startup.m_cameraMarkerCredits.position = CoastalCreditsPosition;
			startup.m_cameraMarkerGame.position = CoastalGamePosition;
			startup.m_cameraMarkerMain.position = CoastalStartMainPosition;
			startup.m_cameraMarkerStart.position = CoastalStartMainPosition;
			startup.m_cameraMarkerSaves.position = CoastalSavesPosition;
			startup.m_cameraMarkerCharacter.rotation = Quaternion.Euler(CoastalCharacterRotation);
			startup.m_cameraMarkerCredits.rotation = Quaternion.Euler(CoastalCreditsRotation);
			startup.m_cameraMarkerGame.rotation = Quaternion.Euler(CoastalGameRotation);
			startup.m_cameraMarkerMain.rotation = Quaternion.Euler(CoastalStartMainRotation);
			startup.m_cameraMarkerStart.rotation = Quaternion.Euler(CoastalStartMainRotation);
			startup.m_cameraMarkerSaves.rotation = Quaternion.Euler(CoastalSavesRotation);
		}

		private static void ApplyPlayerPreview(FejdStartup startup)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			startup.m_characterPreviewPoint.position = CoastalPlayerPosition;
			GameObject playerInstance = GetPlayerInstance(startup);
			if ((Object)(object)playerInstance != (Object)null)
			{
				playerInstance.transform.position = CoastalPlayerPosition;
			}
		}

		private static void RestoreVanillaMarkers(FejdStartup startup)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			SetMarkerPosition(startup.m_cameraMarkerCharacter, _vanillaCharacterPosition);
			SetMarkerPosition(startup.m_cameraMarkerCredits, _vanillaCreditsPosition);
			SetMarkerPosition(startup.m_cameraMarkerGame, _vanillaGamePosition);
			SetMarkerPosition(startup.m_cameraMarkerMain, _vanillaMainPosition);
			SetMarkerPosition(startup.m_cameraMarkerStart, _vanillaStartPosition);
			SetMarkerPosition(startup.m_cameraMarkerSaves, _vanillaSavesPosition);
			SetMarkerRotation(startup.m_cameraMarkerCharacter, _vanillaCharacterRotation);
			SetMarkerRotation(startup.m_cameraMarkerCredits, _vanillaCreditsRotation);
			SetMarkerRotation(startup.m_cameraMarkerGame, _vanillaGameRotation);
			SetMarkerRotation(startup.m_cameraMarkerMain, _vanillaMainRotation);
			SetMarkerRotation(startup.m_cameraMarkerStart, _vanillaStartRotation);
			SetMarkerRotation(startup.m_cameraMarkerSaves, _vanillaSavesRotation);
		}

		private static void RestoreVanillaPlayerPreview(FejdStartup startup)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0059: 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)
			if ((Object)(object)startup.m_characterPreviewPoint != (Object)null)
			{
				startup.m_characterPreviewPoint.position = _vanillaPlayerPosition;
				startup.m_characterPreviewPoint.rotation = Quaternion.Euler(_vanillaPlayerRotation);
			}
			GameObject playerInstance = GetPlayerInstance(startup);
			if ((Object)(object)playerInstance != (Object)null)
			{
				playerInstance.transform.position = _vanillaPlayerPosition;
				playerInstance.transform.rotation = Quaternion.Euler(_vanillaPlayerRotation);
			}
		}

		private static void SetMarkerPosition(Transform? marker, Vector3 position)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)marker != (Object)null)
			{
				marker.position = position;
			}
		}

		private static void SetMarkerRotation(Transform? marker, Vector3 euler)
		{
			//IL_000a: 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)
			if ((Object)(object)marker != (Object)null)
			{
				marker.rotation = Quaternion.Euler(euler);
			}
		}

		private static GameObject? GetPlayerInstance(FejdStartup startup)
		{
			if ((object)_playerInstanceField == null)
			{
				_playerInstanceField = typeof(FejdStartup).GetField("m_playerInstance", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _playerInstanceField?.GetValue(startup);
			return (GameObject?)((obj is GameObject) ? obj : null);
		}

		private static void UpdateDepthOfField(FejdStartup startup)
		{
			if (_depthOfFieldOnCharacterSelect != null && _depthOfFieldOnCharacterSelect.Value)
			{
				Behaviour val = ResolveDepthOfField();
				if (!((Object)(object)val == (Object)null))
				{
					bool enabled = startup.m_characterSelectScreen.activeSelf || startup.m_creditsPanel.activeSelf;
					val.enabled = enabled;
				}
			}
		}

		private static Behaviour? ResolveDepthOfField()
		{
			if ((Object)(object)_cachedDepthOfField != (Object)null)
			{
				return _cachedDepthOfField;
			}
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera == (Object)null)
			{
				return null;
			}
			Behaviour[] components = ((Component)mainCamera).GetComponents<Behaviour>();
			foreach (Behaviour val in components)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "DepthOfField")
				{
					_cachedDepthOfField = val;
					return val;
				}
			}
			return null;
		}

		private static Transform? FindChildTransform(Transform parent, string childName)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (((Object)child).name == childName)
				{
					return child;
				}
				Transform val = FindChildTransform(child, childName);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class Hu
	{
		internal const string StartGameLower = "játék indítása";

		internal const string SettingsLower = "beállitások";

		internal const string PatchNotesTitleLower = "frissítési napló";

		internal const string ModdedMarkerLower = "módosított";
	}
	[BepInPlugin("rdmods.mmheim.mainmenu", "MMOHeim Main Menu", "1.0.0")]
	public sealed class MMOHeimMainMenuPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__73_0;

			internal void <CreateDiscordPanel>b__73_0()
			{
				Application.OpenURL("https://discord.gg/yX9tv3FXY6");
				LogInfo("Discord opened.");
			}
		}

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

			private object <>2__current;

			public float seconds;

			private MMOHeimMainMenuPlugin <plug>5__2;

			private AudioSource <src>5__3;

			private float <v0>5__4;

			private float <t>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<plug>5__2 = null;
				<src>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<plug>5__2 = Instance;
					if ((Object)(object)<plug>5__2?._menuMusicSource == (Object)null)
					{
						StopMenuMusic();
						return false;
					}
					<src>5__3 = <plug>5__2._menuMusicSource;
					<v0>5__4 = <src>5__3.volume;
					<t>5__5 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__5 < seconds && (Object)(object)<src>5__3 != (Object)null)
				{
					<t>5__5 += Time.unscaledDeltaTime;
					<src>5__3.volume = Mathf.Lerp(<v0>5__4, 0f, Mathf.Clamp01(<t>5__5 / seconds));
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)<plug>5__2 != (Object)null)
				{
					<plug>5__2._menuMusicFadeCoroutine = null;
				}
				StopMenuMusic();
				LogInfo("Menu music stopped after fade.");
				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 <HideUnwantedMainMenuUiDelayed>d__60 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					HideMenuClutterOnce();
					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 <LoadAndPlayMusic>d__76 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			private UnityWebRequest <req>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<req>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSecondsRealtime(0.1f);
						<>1__state = 1;
						result = true;
						break;
					case 1:
					{
						<>1__state = -1;
						string musicPath = GetMusicPath();
						if (!File.Exists(musicPath))
						{
							LogWarn("mainmenu.ogg missing: " + musicPath);
							result = false;
							break;
						}
						string absoluteUri = new Uri(Path.GetFullPath(musicPath)).AbsoluteUri;
						<req>5__2 = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)14);
						<>1__state = -3;
						<>2__current = <req>5__2.SendWebRequest();
						<>1__state = 2;
						result = true;
						break;
					}
					case 2:
					{
						<>1__state = -3;
						AudioClip content = DownloadHandlerAudioClip.GetContent(<req>5__2);
						if ((Object)(object)content == (Object)null || (Object)(object)Instance == (Object)null)
						{
							LogWarn("Music failed: " + <req>5__2.error);
							result = false;
						}
						else
						{
							EnsureMenuMusicAudio(Instance);
							AudioSource menuMusicSource = Instance._menuMusicSource;
							menuMusicSource.clip = content;
							menuMusicSource.loop = true;
							menuMusicSource.volume = 0.55f;
							if (!menuMusicSource.isPlaying)
							{
								menuMusicSource.Play();
							}
							LogInfo("Menu music playing.");
							if ((Object)(object)Instance != (Object)null)
							{
								Instance._menuMusicStartCoroutine = null;
							}
							result = false;
						}
						<>m__Finally1();
						break;
					}
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<req>5__2 != null)
				{
					((IDisposable)<req>5__2).Dispose();
				}
			}

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

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

			private object <>2__current;

			public MMOHeimMainMenuPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Expected O, but got Unknown
				int num = <>1__state;
				MMOHeimMainMenuPlugin mMOHeimMainMenuPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if ((Object)(object)_discordLogoImage == (Object)null)
					{
						return false;
					}
					string discordLogoPath = GetDiscordLogoPath();
					if (!File.Exists(discordLogoPath))
					{
						return false;
					}
					Sprite val = LoadSpriteFromDisk(discordLogoPath);
					if ((Object)(object)val != (Object)null && (Object)(object)_discordLogoImage != (Object)null)
					{
						_discordLogoImage.sprite = val;
						_discordLogoImage.overrideSprite = val;
						_discordLogoImage.type = (Type)0;
						((Graphic)_discordLogoImage).color = Color.white;
						((Graphic)_discordLogoImage).material = null;
						foreach (Transform item in ((Component)_discordLogoImage).transform)
						{
							Transform val2 = item;
							if (((Object)val2).name == "DiscordGlyph")
							{
								((Component)val2).gameObject.SetActive(false);
							}
						}
					}
					mMOHeimMainMenuPlugin._discordLogoCoroutine = null;
					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 <MaintainMenuAtmosphereWhileOnMainMenu>d__56 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			private WaitForSecondsRealtime <wait>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<wait>5__2 = new WaitForSecondsRealtime(0.25f);
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (MainMenuActive && (Object)(object)Instance != (Object)null)
				{
					MenuAtmosphere.MaintainAppliedState();
					<>2__current = <wait>5__2;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)Instance != (Object)null)
				{
					Instance._menuAtmosphereCoroutine = null;
				}
				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 <MuteVanillaMenuMusicOnceDelayed>d__57 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Instance != (Object)null && MainMenuActive)
					{
						MuteVanillaMenuMusicNow();
					}
					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 <ReplaceLogoDelayed>d__64 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSecondsRealtime(0.75f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					FejdStartup val = Object.FindFirstObjectByType<FejdStartup>();
					if ((Object)(object)val == (Object)null || !File.Exists(GetLogoPath()))
					{
						return false;
					}
					Image val2 = null;
					int num = int.MinValue;
					Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
					foreach (Image val3 in componentsInChildren)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							int num2 = ScoreLogo(val3);
							if (num2 > num)
							{
								num = num2;
								val2 = val3;
							}
						}
					}
					if ((Object)(object)val2 != (Object)null && num >= 50)
					{
						Sprite val4 = LoadSpriteFromDisk(GetLogoPath());
						if ((Object)(object)val4 != (Object)null)
						{
							ApplyLogo(val2, val4);
							LogInfo($"Logo applied (score {num}).");
						}
					}
					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 const string ModGuid = "rdmods.mmheim.mainmenu";

		public const string ModName = "MMOHeim Main Menu";

		public const string AssetFolderName = "MMOheimMainMenu";

		public const string LoadingArtFolderName = "LoadingArt";

		public const int LoadingArtMaxSlot = 12;

		public const string DiscordInviteUrl = "https://discord.gg/yX9tv3FXY6";

		public const string DiscordTitleText = "Need help? Join Discord!";

		public const string DiscordButtonText = "Click here to join Discord!";

		internal static bool MenuMusicFadeCommittedForSession;

		internal static volatile bool MainMenuActive;

		internal static readonly bool EnableCustomLoadingScreens = true;

		private ConfigEntry<bool>? _enableLogging;

		private Harmony? _harmony;

		private GameObject? _menuMusicGo;

		private AudioSource? _menuMusicSource;

		private Coroutine? _menuMusicFadeCoroutine;

		private Coroutine? _menuMusicStartCoroutine;

		private Coroutine? _menuAtmosphereCoroutine;

		private Coroutine? _menuAtmosphereApplyCoroutine;

		private static GameObject? _discordPanel;

		private Coroutine? _discordLogoCoroutine;

		private static Image? _discordLogoImage;

		private static readonly HashSet<string> NeverHide = new HashSet<string>(StringComparer.Ordinal) { "startgui", "worldpanel", "startgame", "topleft", "topright", "menu", "joinpanel", "panel", "tooltips" };

		internal static MMOHeimMainMenuPlugin? Instance { get; private set; }

		internal static ConfigEntry<bool>? ModEnabled { get; private set; }

		internal static ManualLogSource? ModLog { get; private set; }

		internal static GameObject? DiscordPanelRoot => _discordPanel;

		internal static void SetDiscordPanelRoot(GameObject? panel)
		{
			_discordPanel = panel;
		}

		private void Awake()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			Instance = this;
			ModLog = ((BaseUnityPlugin)this).Logger;
			MenuMusicFadeCommittedForSession = false;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn this mod on or off.");
			_enableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLogging", false, "Write informational logs (menu lifecycle, loading watcher, atmosphere, Discord visibility). Delete cfg after changing.");
			DiscordPanelVisibility.BindConfig(((BaseUnityPlugin)this).Config);
			MenuAtmosphere.BindConfig(((BaseUnityPlugin)this).Config);
			MenuScenery.BindConfig(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Config.Save();
			if (!ModEnabled.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"MMOHeim Main Menu is disabled in config.");
				return;
			}
			EnsureAssetDirectories();
			_harmony = new Harmony("rdmods.mmheim.mainmenu");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("MMOHeim Main Menu loaded. Asset root: " + GetAssetRootPath()));
		}

		private void OnDestroy()
		{
			if (_discordLogoCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_discordLogoCoroutine);
				_discordLogoCoroutine = null;
			}
			if (_menuMusicFadeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_menuMusicFadeCoroutine);
				_menuMusicFadeCoroutine = null;
			}
			if (_menuMusicStartCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_menuMusicStartCoroutine);
				_menuMusicStartCoroutine = null;
			}
			if (_menuAtmosphereCoroutine != null)
			{
				((MonoBehaviour)this).StopC