Decompiled source of FehuLanding v420.101.24

BepInEx/plugins/FehuLanding/FehuLanding.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("420.101.20.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("420.101.20.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TheFehu
{
	internal sealed class ActiveServerQuery
	{
		public readonly ServerQueryWorkItem Item;

		public readonly string CacheKey;

		public readonly int Generation;

		public readonly HServerQuery Handle;

		public readonly ISteamMatchmakingPingResponse Handler;

		public readonly StatusQueryCallback Callback;

		public readonly DateTime StartedUtc;

		public bool Cancelled;

		public ActiveServerQuery(ServerQueryWorkItem item, string cacheKey, int generation, HServerQuery handle, StatusQueryCallback callback)
		{
			//IL_001c: 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)
			Item = item;
			CacheKey = cacheKey;
			Generation = generation;
			Handle = handle;
			Callback = callback;
			Handler = callback.Handler;
			StartedUtc = DateTime.UtcNow;
		}

		public void DisposeCallback()
		{
			Callback?.Dispose();
		}
	}
	[Serializable]
	public sealed class FehuContent
	{
		public int schemaVersion;

		public string telemetryUrl;

		public FehuUiText uiText;

		public List<FehuShortcutText> shortcuts;

		public string newsTitle;

		public string newsText;

		public string sagaTitle;

		public string sagaText;

		public string realmsTitle;

		public int ServerIconSize;

		public int ServerIconSpacing;

		public SocialPanelSettings socialPanel;

		public List<SocialLink> socialLinks;

		public List<FehuServer> servers;

		public FehuLinks links;

		public List<MiniPanelSettings> miniPanels;

		public static FehuContent CreateDefault()
		{
			return new FehuContent
			{
				schemaVersion = 3,
				telemetryUrl = "https://www.forteca.net/",
				uiText = FehuUiText.CreateDefault(),
				shortcuts = FehuShortcutText.CreateDefaults(),
				newsTitle = "Roadmap",
				sagaTitle = "Saga Chronicles",
				realmsTitle = "FEHU REALMS",
				newsText = "# Latest News\n---\nShared Clans are now live.\n\nClan portals now use exact permissions.\n\nGames framework expanded.\n---\n# Upcoming\n---\nSkald Saga Integration\nKingdom Buildings\nNPC Guards",
				sagaText = "Connecting...",
				servers = new List<FehuServer>
				{
					new FehuServer("Fehu 10th World - MASTER", "play.forteca.net", 2456, string.Empty, string.Empty, "fehu-10th-world")
					{
						icon = "1_fehu_10th.png",
						description = "The Eternal Realm\nKingdoms • Clans • Territory Wars\nOne world. No wipes. Your history remains."
					},
					new FehuServer("Fehu Conquest", "play.forteca.net", 2462, string.Empty, string.Empty, "fehu-conquest")
					{
						icon = "2_fehu_conquest.png",
						description = "Clans & Freeborns Warfare\nDifficulty: Hard"
					},
					new FehuServer("Fehu Dominion", "play.forteca.net", 2464, string.Empty, string.Empty, "fehu-dominion")
					{
						icon = "3_fehu_dominion.png",
						description = "Freeborns & Clans Warfare\nDifficulty: Hard"
					},
					new FehuServer("Fehu Immersive", "play.forteca.net", 2460, string.Empty, string.Empty, "fehu-immersive")
					{
						icon = "4_fehu_immersive.png",
						description = "Very Hard World"
					},
					new FehuServer("Fehu Adventure", "play.forteca.net", 2458, string.Empty, string.Empty, "fehu-adventure")
					{
						icon = "5_fehu_adventure.png",
						queryPort = 2459,
						steamIdIcon = true,
						description = "Events and Expeditions"
					},
					new FehuServer("BuildHeim", "play.forteca.net", 2468, string.Empty, string.Empty, "buildheim")
					{
						icon = "6_buildheim.png",
						queryPort = 2469,
						steamIdIcon = true,
						description = "Blueprints Valhalla"
					},
					new FehuServer("Blackheim", "play.forteca.net", 2484, string.Empty, string.Empty, "blackheim")
					{
						icon = "7_blackheim.png",
						queryPort = 2485,
						description = "Black's Vanilla"
					},
					new FehuServer("Warheim", "play.forteca.net", 2478, string.Empty, string.Empty, "warheim")
					{
						icon = "8_warheim.png",
						queryPort = 2479,
						description = "PvP Only"
					},
					new FehuServer("ValBase", "play.forteca.net", 2482, string.Empty, string.Empty, "valbase")
					{
						icon = "9_valbase.png",
						queryPort = 2483,
						description = "Pure Vanilla"
					},
					new FehuServer("Test Server", "play.forteca.net", 2480, string.Empty, string.Empty, "forteca-test")
					{
						icon = "10_test-server.png",
						queryPort = 2481,
						steamIdIcon = true,
						description = "Development & Testing Realm"
					}
				},
				links = new FehuLinks
				{
					discord = "https://discord.gg/YOURCODE",
					website = "https://forteca.net",
					support = "https://forteca.tip4serv.com/",
					wiki = "https://codex.forteca.net",
					kingdoms = "https://forteca.net/_cw",
					rankings = "https://forteca.net/_modix",
					leaderboard = "https://forteca.net/_cw/rank/"
				},
				ServerIconSize = 28,
				ServerIconSpacing = 6
			};
		}
	}
	internal static class FehuJson
	{
		internal const string DefaultText = "{ \"schemaVersion\": 3 }";

		internal static FehuContent Parse(string json)
		{
			if (string.IsNullOrWhiteSpace(json))
			{
				return null;
			}
			FehuContent fehuContent = FehuContent.CreateDefault();
			string json2 = ReadSection(json, "uiText", '{', '}');
			FehuUiText fehuUiText = fehuContent.uiText ?? FehuUiText.CreateDefault();
			FehuUiText fehuUiText2 = new FehuUiText
			{
				fehuRealmsTitle = ReadString(json2, "fehuRealmsTitle", ReadString(json, "realmsTitle", fehuUiText.fehuRealmsTitle)),
				otherRealmsTitle = ReadString(json2, "otherRealmsTitle", ReadString(json, "otherRealmsTitle", fehuUiText.otherRealmsTitle)),
				roadmapTitle = ReadString(json2, "roadmapTitle", ReadString(json, "newsTitle", fehuUiText.roadmapTitle)),
				sagaTitle = ReadString(json2, "sagaTitle", ReadString(json, "sagaTitle", fehuUiText.sagaTitle)),
				play = ReadString(json2, "play", fehuUiText.play),
				character = ReadString(json2, "character", fehuUiText.character),
				settings = ReadString(json2, "settings", fehuUiText.settings),
				quit = ReadString(json2, "quit", fehuUiText.quit),
				wiki = ReadString(json2, "wiki", fehuUiText.wiki),
				support = ReadString(json2, "support", fehuUiText.support),
				kingdoms = ReadString(json2, "kingdoms", fehuUiText.kingdoms),
				rankings = ReadString(json2, "rankings", fehuUiText.rankings),
				playerLog = ReadString(json2, "playerLog", fehuUiText.playerLog),
				leaderboard = ReadString(json2, "leaderboard", fehuUiText.leaderboard),
				motto = ReadString(json2, "motto", fehuUiText.motto)
			};
			FehuContent fehuContent2 = new FehuContent
			{
				schemaVersion = ReadInt(json, "schemaVersion", 2),
				telemetryUrl = ReadString(json, "telemetryUrl", fehuContent.telemetryUrl),
				uiText = fehuUiText2,
				shortcuts = new List<FehuShortcutText>(),
				newsTitle = fehuUiText2.roadmapTitle,
				newsText = ReadString(json, "roadmapText", ReadString(json, "newsText", ReadString(json, "leftText", fehuContent.newsText))),
				sagaTitle = fehuUiText2.sagaTitle,
				sagaText = NormalizeSagaText(ReadString(json, "sagaFallbackText", ReadString(json, "sagaText", fehuContent.sagaText))),
				realmsTitle = fehuUiText2.fehuRealmsTitle,
				servers = new List<FehuServer>(),
				links = new FehuLinks(),
				miniPanels = new List<MiniPanelSettings>(),
				ServerIconSize = ReadInt(json, "ServerIconSize", fehuContent.ServerIconSize),
				ServerIconSpacing = ReadInt(json, "ServerIconSpacing", fehuContent.ServerIconSpacing)
			};
			fehuContent2.socialPanel = new SocialPanelSettings
			{
				Enabled = true,
				X = -20,
				Y = 35,
				Width = 620,
				Height = 80,
				IconSize = 42,
				IconSpacing = 8
			};
			string json3 = ReadSection(json, "SocialPanel", '{', '}');
			fehuContent2.socialPanel.Enabled = ReadBool(json3, "Enabled", fehuContent2.socialPanel.Enabled);
			fehuContent2.socialPanel.X = ReadInt(json3, "X", fehuContent2.socialPanel.X);
			fehuContent2.socialPanel.Y = ReadInt(json3, "Y", fehuContent2.socialPanel.Y);
			fehuContent2.socialPanel.Width = ReadInt(json3, "Width", fehuContent2.socialPanel.Width);
			fehuContent2.socialPanel.Height = ReadInt(json3, "Height", fehuContent2.socialPanel.Height);
			fehuContent2.socialPanel.IconSize = ReadInt(json3, "IconSize", fehuContent2.socialPanel.IconSize);
			fehuContent2.socialPanel.IconSpacing = ReadInt(json3, "IconSpacing", fehuContent2.socialPanel.IconSpacing);
			fehuContent2.socialLinks = new List<SocialLink>();
			foreach (Match item in Regex.Matches(ReadSection(json, "socialLinks", '[', ']') ?? ReadSection(json, "SocialLinks", '[', ']') ?? string.Empty, "\\{(?<item>[^{}]*)\\}"))
			{
				string value = item.Groups["item"].Value;
				fehuContent2.socialLinks.Add(new SocialLink
				{
					Title = ReadString(value, "Title", "?"),
					Icon = ReadString(value, "Icon", ""),
					Url = ReadString(value, "Url", "")
				});
			}
			foreach (Match item2 in Regex.Matches(ReadSection(json, "shortcuts", '[', ']') ?? string.Empty, "\\{(?<item>[^{}]*)\\}"))
			{
				string value2 = item2.Groups["item"].Value;
				string text = ReadString(value2, "key", string.Empty).Trim().ToUpperInvariant();
				if (Regex.IsMatch(text, "^F(?:[1-9]|10)$"))
				{
					fehuContent2.shortcuts.Add(new FehuShortcutText
					{
						key = text,
						label = ReadString(value2, "label", string.Empty)
					});
				}
			}
			if (fehuContent2.shortcuts.Count == 0)
			{
				fehuContent2.shortcuts = FehuShortcutText.CreateDefaults();
			}
			foreach (Match item3 in Regex.Matches(ReadSection(json, "MiniPanels", '[', ']') ?? "", "\\{(?<item>[^{}]*)\\}"))
			{
				string value3 = item3.Groups["item"].Value;
				fehuContent2.miniPanels.Add(new MiniPanelSettings
				{
					Enabled = ReadBool(value3, "Enabled", fallback: false),
					X = ReadInt(value3, "X", 0),
					Y = ReadInt(value3, "Y", 0),
					Width = ReadInt(value3, "Width", fehuContent2.socialPanel.Width / 2),
					Height = ReadInt(value3, "Height", fehuContent2.socialPanel.Height),
					Icon = ReadString(value3, "Icon", ""),
					Icons = ReadString(value3, "Icons", ""),
					Url = ReadString(value3, "Url", ""),
					Text = ReadString(value3, "Text", "")
				});
			}
			foreach (Match item4 in Regex.Matches(ReadSection(json, "servers", '[', ']') ?? string.Empty, "\\{(?<server>[^{}]*)\\}"))
			{
				string value4 = item4.Groups["server"].Value;
				if (ReadString(value4, "name", string.Empty).IndexOf("aurora", StringComparison.OrdinalIgnoreCase) < 0 && ReadString(value4, "id", string.Empty).IndexOf("aurora", StringComparison.OrdinalIgnoreCase) < 0)
				{
					int num = ReadInt(value4, "port", 2456);
					fehuContent2.servers.Add(new FehuServer(ReadString(value4, "name", "Unnamed server"), NormalizeJsonServerAddress(ReadString(value4, "address", string.Empty)), num, string.Empty, string.Empty, ReadString(value4, "id", string.Empty))
					{
						queryPort = ReadInt(value4, "queryPort", num + 1),
						password = ReadString(value4, "password", string.Empty),
						description = ReadString(value4, "description", string.Empty),
						icon = ReadString(value4, "icon", string.Empty),
						steamIdIcon = ReadBool(value4, "steamIdIcon", fallback: false)
					});
				}
			}
			if (fehuContent2.servers.Count == 0)
			{
				fehuContent2.servers = fehuContent.servers;
			}
			string json4 = ReadSection(json, "links", '{', '}');
			fehuContent2.links.discord = ReadString(json4, "discord", fehuContent.links.discord);
			fehuContent2.links.website = ReadString(json4, "website", fehuContent.links.website);
			fehuContent2.links.support = ReadString(json4, "support", fehuContent.links.support);
			fehuContent2.links.wiki = ReadString(json4, "wiki", fehuContent.links.wiki);
			fehuContent2.links.kingdoms = ReadString(json4, "kingdoms", fehuContent.links.kingdoms);
			fehuContent2.links.rankings = ReadString(json4, "rankings", fehuContent.links.rankings);
			fehuContent2.links.leaderboard = ReadString(json4, "leaderboard", fehuContent.links.leaderboard);
			return fehuContent2;
		}

		private static string NormalizeJsonServerAddress(string address)
		{
			object obj;
			if (!string.Equals((address ?? string.Empty).Trim(), "forteca.net", StringComparison.OrdinalIgnoreCase))
			{
				obj = address;
				if (obj == null)
				{
					return string.Empty;
				}
			}
			else
			{
				obj = "play.forteca.net";
			}
			return (string)obj;
		}

		private static string NormalizeSagaText(string value)
		{
			if (!string.Equals((value ?? string.Empty).Trim(), "The saga has not begun yet.", StringComparison.OrdinalIgnoreCase))
			{
				return value;
			}
			return "Connecting...";
		}

		private static string ReadString(string json, string key, string fallback)
		{
			if (json == null)
			{
				return fallback;
			}
			Match match = Regex.Match(json, "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*\\\"(?<value>(?:\\\\.|[^\\\"])*)\\\"");
			if (!match.Success)
			{
				return fallback;
			}
			return Regex.Unescape(match.Groups["value"].Value);
		}

		private static int ReadInt(string json, string key, int fallback)
		{
			Match match = Regex.Match(json ?? string.Empty, "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*(?<value>-?\\d+)");
			if (!match.Success || !int.TryParse(match.Groups["value"].Value, out var result))
			{
				return fallback;
			}
			return result;
		}

		private static bool ReadBool(string json, string key, bool fallback)
		{
			Match match = Regex.Match(json ?? "", "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*(?<value>true|false)", RegexOptions.IgnoreCase);
			if (!match.Success || !bool.TryParse(match.Groups["value"].Value, out var result))
			{
				return fallback;
			}
			return result;
		}

		private static string ReadSection(string json, string key, char open, char close)
		{
			int num = json.IndexOf("\"" + key + "\"", StringComparison.Ordinal);
			if (num < 0)
			{
				return null;
			}
			int num2 = json.IndexOf(open, num);
			if (num2 < 0)
			{
				return null;
			}
			int num3 = 0;
			for (int i = num2; i < json.Length; i++)
			{
				if (json[i] == open)
				{
					num3++;
				}
				if (json[i] == close && --num3 == 0)
				{
					return json.Substring(num2 + 1, i - num2 - 1);
				}
			}
			return null;
		}
	}
	[Serializable]
	public sealed class FehuLinks
	{
		public string discord;

		public string website;

		public string support;

		public string wiki;

		public string kingdoms;

		public string rankings;

		public string leaderboard;
	}
	internal sealed class FehuLogger
	{
		private readonly ManualLogSource _source;

		private readonly HashSet<string> _once = new HashSet<string>(StringComparer.Ordinal);

		private readonly Dictionary<string, DateTime> _lastLogUtc = new Dictionary<string, DateTime>(StringComparer.Ordinal);

		private readonly object _sync = new object();

		internal bool DebugLogging { get; private set; }

		internal FehuLogger(ManualLogSource source, bool debugLogging)
		{
			_source = source ?? throw new ArgumentNullException("source");
			DebugLogging = debugLogging;
		}

		internal void SetDebugLogging(bool enabled)
		{
			DebugLogging = enabled;
		}

		internal void LogInfo(object message)
		{
			LogDebug(message);
		}

		internal void LogDebug(object message)
		{
			if (DebugLogging)
			{
				_source.LogDebug(message);
			}
		}

		internal void LogInfoOnce(string key, object message)
		{
			if (string.IsNullOrEmpty(key))
			{
				key = Convert.ToString(message) ?? string.Empty;
			}
			lock (_sync)
			{
				if (!_once.Add(key))
				{
					return;
				}
			}
			_source.LogInfo(message);
		}

		internal void LogDebugOnce(string key, object message)
		{
			if (!DebugLogging)
			{
				return;
			}
			lock (_sync)
			{
				if (!_once.Add("debug:" + key))
				{
					return;
				}
			}
			_source.LogDebug(message);
		}

		internal void LogDebugThrottled(string key, object message, TimeSpan interval)
		{
			if (!DebugLogging)
			{
				return;
			}
			DateTime utcNow = DateTime.UtcNow;
			lock (_sync)
			{
				if (_lastLogUtc.TryGetValue(key, out var value) && utcNow - value < interval)
				{
					return;
				}
				_lastLogUtc[key] = utcNow;
			}
			_source.LogDebug(message);
		}

		internal void LogStartup(object message)
		{
			_source.LogInfo(message);
		}

		internal void LogWarning(object message)
		{
			_source.LogWarning(message);
		}

		internal void LogError(object message)
		{
			_source.LogError(message);
		}
	}
	public sealed class FehuMenu : MonoBehaviour
	{
		private sealed class SagaFeedEntry
		{
			public DateTime TimestampUtc;

			public string RealmDisplayName;

			public string Category;

			public string Title;

			public string Text;

			public string Priority;
		}

		private sealed class ClassicUiAssets
		{
			public string Name;

			public Texture2D Background;

			public Texture2D Frame;

			public Texture2D Header;

			public Texture2D Separator;

			public Texture2D Button;

			public Texture2D ButtonHover;

			public Texture2D ButtonActive;

			public Texture2D CloseButton;

			public Texture2D Panel;

			public Texture2D BottomPanel;

			public Texture2D Badge;
		}

		[CompilerGenerated]
		private static class _003C_003EO
		{
			public static UnityAction _003C1_003E__OpenSupportUrl;
		}

		private sealed class TelemetryReading
		{
			internal int? Day;

			internal string Name;

			internal string AmpName;

			internal int Players = -1;

			internal int MaxPlayers = -1;

			internal bool Running;

			internal DateTime ExpiresUtc;
		}

		private sealed class WorldDayTarget
		{
			internal string Id;

			internal int Port;

			internal int Session;

			internal Stopwatch Clock;

			internal long RequestStartedMilliseconds;
		}

		private sealed class WorldDayResult
		{
			internal WorldDayTarget Target;

			internal TelemetryReading Reading;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OpenSupportUrl;
		}

		private static FehuMenu _activeLandingRoot;

		private const float ReferenceWidth = 1920f;

		private const float ReferenceHeight = 1080f;

		private ConfigEntry<bool> _enabled;

		private ConfigEntry<bool> _showOnMainMenu;

		private ConfigEntry<bool> _hideChangelog;

		private ConfigEntry<bool> _hideMerchStore;

		private ConfigEntry<bool> _hideVersionText;

		private ConfigEntry<bool> _hideModdedWarningText;

		private ConfigEntry<bool> _hideShowLogButton;

		private ConfigEntry<bool> _newsEnabled;

		private ConfigEntry<bool> _sagaEnabled;

		private ConfigEntry<bool> _realmsEnabled;

		private ConfigEntry<bool> _otherRealmsEnabled;

		private ConfigEntry<bool> _socialEnabled;

		private ConfigEntry<bool> _enablePanelDragging;

		private ConfigEntry<bool> _enableSteamIdIcons;

		private ConfigEntry<bool> _enableLiveStatus;

		private ConfigEntry<int> _rightX;

		private ConfigEntry<int> _rightY;

		private ConfigEntry<int> _rightWidth;

		private ConfigEntry<int> _rightHeight;

		private ConfigEntry<int> _otherX;

		private ConfigEntry<int> _otherY;

		private ConfigEntry<int> _otherWidth;

		private ConfigEntry<int> _otherHeight;

		private ConfigEntry<int> _newsX;

		private ConfigEntry<int> _newsY;

		private ConfigEntry<int> _newsWidth;

		private ConfigEntry<int> _newsHeight;

		private ConfigEntry<int> _sagaX;

		private ConfigEntry<int> _sagaY;

		private ConfigEntry<int> _sagaWidth;

		private ConfigEntry<int> _sagaHeight;

		private ConfigEntry<int> _socialX;

		private ConfigEntry<int> _socialY;

		private ConfigEntry<int> _socialWidth;

		private ConfigEntry<int> _socialHeight;

		private ConfigEntry<int> _statusRefreshIntervalSeconds;

		private ConfigEntry<int> _queryTimeoutMilliseconds;

		private ConfigEntry<int> _queryRetryCount;

		private ConfigEntry<int> _retryDelayMilliseconds;

		private ConfigEntry<int> _initialStaggerMilliseconds;

		private ConfigEntry<int> _offlineConfirmationCycles;

		private ConfigEntry<int> _onlineConfirmationCycles;

		private ConfigEntry<string> _newsTitle;

		private ConfigEntry<string> _sagaTitle;

		private ConfigEntry<string> _realmsTitle;

		private ConfigEntry<string> _otherRealmsTitle;

		private ConfigEntry<float> _uiScale;

		private Texture2D _bottomPanel;

		private ConfigEntry<bool> _showPlayerCounts;

		private ConfigEntry<bool> _pauseWhenLandingHidden;

		private ConfigEntry<bool> _logOnlyStateChanges;

		private ConfigEntry<bool> _debugStatusQueries;

		private ConfigEntry<bool> _enableLayoutDiagnostics;

		private ConfigEntry<bool> _keepLastKnownStatusWhileChecking;

		private ConfigEntry<bool> _bottomLegendEnabled;

		private ConfigEntry<bool> _leftLegendEnabled;

		private ConfigEntry<bool> _rightLegendEnabled;

		private ConfigEntry<bool> _legendF1Enabled;

		private ConfigEntry<bool> _legendF3Enabled;

		private ConfigEntry<bool> _legendF4Enabled;

		private ConfigEntry<bool> _legendF6Enabled;

		private ConfigEntry<bool> _legendF7Enabled;

		private ConfigEntry<bool> _legendF8Enabled;

		private ConfigEntry<bool> _legendF9Enabled;

		private ConfigEntry<bool> _legendF10Enabled;

		private ConfigEntry<bool> _steamIdLegendEnabled;

		private ConfigEntry<bool> _joinLegendEnabled;

		private ConfigEntry<string> _legendF1Label;

		private ConfigEntry<string> _legendF3Label;

		private ConfigEntry<string> _legendF4Label;

		private ConfigEntry<string> _legendF6Label;

		private ConfigEntry<string> _legendF7Label;

		private ConfigEntry<string> _legendF8Label;

		private ConfigEntry<string> _legendF9Label;

		private ConfigEntry<string> _legendF10Label;

		private ConfigEntry<string> _steamIdLegendLabel;

		private ConfigEntry<string> _steamIdLegendText;

		private ConfigEntry<string> _joinLegendTitle;

		private ConfigEntry<string> _joinLegendText;

		private ConfigEntry<int> _socialIconSize;

		private ConfigEntry<int> _socialIconSpacing;

		private ConfigEntry<int> _bottomLeftLegendX;

		private ConfigEntry<int> _bottomLeftLegendY;

		private ConfigEntry<int> _bottomRightLegendX;

		private ConfigEntry<int> _bottomRightLegendY;

		private ConfigEntry<bool>[] _miniEnabled;

		private ConfigEntry<int>[] _miniX;

		private ConfigEntry<int>[] _miniY;

		private ConfigEntry<int>[] _miniWidth;

		private ConfigEntry<int>[] _miniHeight;

		private ConfigEntry<string>[] _miniText;

		private ConfigEntry<string>[] _miniIcons;

		private ConfigEntry<string>[] _miniUrl;

		private FehuContent _content;

		private string _contentPath;

		private bool _useAnchoredDefaultLayout;

		private ConfigEntry<int> _layoutVersion;

		private ConfigEntry<int> _configVersion;

		private ConfigEntry<bool> _resetLayout;

		private ConfigEntry<int> _finalLeftOffsetX;

		private ConfigEntry<int> _finalLeftOffsetY;

		private ConfigEntry<int> _finalRoadmapOffsetX;

		private ConfigEntry<int> _finalRoadmapOffsetY;

		private ConfigEntry<int> _finalSagaOffsetX;

		private ConfigEntry<int> _finalSagaOffsetY;

		private ConfigEntry<int> _finalHubOffsetX;

		private ConfigEntry<int> _finalHubOffsetY;

		private ConfigEntry<int> _finalBottomBarOffsetX;

		private ConfigEntry<int> _finalBottomBarOffsetY;

		private bool _hiddenForSession;

		private bool _topLeftVisible = true;

		private bool _bottomLeftVisible = true;

		private bool _topRightVisible = true;

		private bool _bottomRightVisible = true;

		private bool _bottomLeftLegendVisible = true;

		private bool _bottomRightLegendVisible = true;

		private bool _socialVisible = true;

		private readonly bool[] _miniVisible = new bool[3] { true, true, true };

		private string _dragPanelId;

		private Vector2 _dragOffset;

		private Vector2 _newsScroll;

		private Vector2 _sagaScroll;

		private GUIStyle _titleStyle;

		private GUIStyle _bodyStyle;

		private GUIStyle _serverStyle;

		private GUIStyle _buttonStyle;

		private GUIStyle _closeButtonStyle;

		private Texture2D _parchment;

		private Texture2D _ink;

		private Texture2D _gold;

		private Texture2D _fade;

		private Texture2D _joinIcon;

		private Texture2D _onlineIcon;

		private Texture2D _offlineIcon;

		private Texture2D _checkIcon;

		private Texture2D _steamIdIcon;

		private readonly HashSet<string> _hiddenLog = new HashSet<string>();

		private readonly HashSet<string> _socialIconLog = new HashSet<string>();

		private readonly Dictionary<string, Texture2D> _socialIcons = new Dictionary<string, Texture2D>();

		private readonly Dictionary<string, Texture2D> _assetIcons = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

		private readonly HashSet<string> _missingStatusIcons = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private readonly HashSet<string> _missingDrawTextureLog = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, ConfigEntry<bool>> _serverSteamIdIconEntries = new Dictionary<string, ConfigEntry<bool>>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, ServerRuntimeState> _serverStates = new Dictionary<string, ServerRuntimeState>();

		private readonly Dictionary<string, string> _lastQueryFailureLog = new Dictionary<string, string>();

		private readonly Dictionary<string, DateTime> _lastLogUtc = new Dictionary<string, DateTime>();

		private readonly Dictionary<string, int> _realmDescriptionFontSizeCache = new Dictionary<string, int>(StringComparer.Ordinal);

		private readonly Dictionary<string, string[]> _serverDescriptionLinesCache = new Dictionary<string, string[]>(StringComparer.Ordinal);

		private readonly Dictionary<string, string[]> _miniIconListCache = new Dictionary<string, string[]>(StringComparer.Ordinal);

		private readonly List<FehuServer> _fehuRealmServers = new List<FehuServer>();

		private readonly List<FehuServer> _otherRealmServers = new List<FehuServer>();

		private readonly List<SagaFeedEntry> _chronicleEntries = new List<SagaFeedEntry>();

		private readonly float[] _shortcutEntryWidths = new float[8];

		private readonly int[] _shortcutEntryIndexes = new int[8];

		private readonly GUIContent _measureContent = new GUIContent();

		private ConfigEntry<bool>[] _leftShortcutEnabled;

		private ConfigEntry<string>[] _leftShortcutLabels;

		private ConfigEntry<bool>[] _rightShortcutEnabled;

		private ConfigEntry<string>[] _rightShortcutLabels;

		private static readonly string[] LeftShortcutIcons = new string[4];

		private static readonly string[] LeftShortcutDefaults = new string[4]
		{
			string.Empty,
			string.Empty,
			string.Empty,
			"Toggle UI"
		};

		private static readonly string[] RightShortcutIcons = new string[8];

		private static readonly string[] RightShortcutDefaults = new string[8] { "Configs", "Kingdoms", "Vault", "Rumble", "HERALDRY", "Rewards", "Factions", "Free" };

		private static readonly string[] MainRealmDescriptionLines = new string[3] { "The Eternal Realm", "One Save To Rule Them All", "Market • Settlement" };

		private int _lastRealmAutoFitScreenWidth;

		private int _lastRealmAutoFitScreenHeight;

		private int _lastRealmAutoFitPanelWidth;

		private float _lastRealmAutoFitUiScale = -1f;

		private DateTime _lastServerQueryUtc = DateTime.MinValue;

		private bool _serverQueriesRunning;

		private readonly Queue<ServerQueryWorkItem> _serverQueryQueue = new Queue<ServerQueryWorkItem>();

		private readonly Dictionary<string, ActiveServerQuery> _activeServerQueries = new Dictionary<string, ActiveServerQuery>(StringComparer.OrdinalIgnoreCase);

		private readonly List<ActiveServerQuery> _activeServerQueryCancelScratch = new List<ActiveServerQuery>(1);

		private int _statusGeneration;

		private bool _statusRuntimeAlive = true;

		private bool _socialIconsLoaded;

		private bool _liveStatusDisabledLogged;

		private static readonly bool IsolationI1DisableNativeServerPolling = false;

		private bool _isolationI1SuppressionLogged;

		private bool _isolationI1ShutdownLogged;

		private static readonly bool IsolationI2StaticRuntime = false;

		private bool _isolationI2StartupLogged;

		private bool _isolationI2RuntimeLogged;

		private bool _isolationI2ShutdownLogged;

		private static readonly bool IsolationI3MinimalShell = false;

		private bool _isolationI3LoadedLogged;

		private bool _isolationI3ShutdownLogged;

		private static readonly bool IsolationI4StartupOnly = false;

		private bool _isolationI4StartupLogged;

		private bool _isolationI4ShutdownLogged;

		private static readonly bool CrashIsolationDiagnosticBuild = false;

		private ConfigEntry<bool> _isoUIRoot;

		private ConfigEntry<bool> _isoMainPanels;

		private ConfigEntry<bool> _isoBottomPanels;

		private ConfigEntry<bool> _isoServerPanels;

		private ConfigEntry<bool> _isoChronicleSaga;

		private ConfigEntry<bool> _isoSocialShortcutPanels;

		private ConfigEntry<bool> _isoClassicUiStyles;

		private ConfigEntry<bool> _isoIconsTexturesSprites;

		private ConfigEntry<bool> _isoLayoutSetup;

		private ConfigEntry<bool> _isoSteam;

		private ConfigEntry<bool> _isoRuntimeSystems;

		private bool _isolationSettingsLogged;

		private bool _isolationSceneBuilt;

		private bool _isolationSceneSkipLogged;

		private int _isolationTexturesCreated;

		private int _isolationSpritesCreated;

		private int _isolationFontsResolved;

		private int _isolationGuiStylesCreated;

		private bool _isolationAssetTotalsLogged;

		private readonly HashSet<string> _isolationGroupsLogged = new HashSet<string>(StringComparer.Ordinal);

		private GUIStyle _isolationLabelStyle;

		private GUIStyle _isolationBoxStyle;

		private readonly Dictionary<string, DateTime> _lastCrashDiagUtcByKey = new Dictionary<string, DateTime>();

		private int _queryHandlesCreated;

		private int _queryHandlesReleased;

		private int _queryStaleCallbacks;

		private Texture2D _supportLogo;

		private Sprite _supportLogoSprite;

		private readonly HashSet<string> _replacedMerch = new HashSet<string>();

		private bool _merchClickBlockedThisMenu;

		private static readonly bool DisableChronicleRefreshIsolation = false;

		private static readonly bool DisableAllRuntimeSchedulersIsolation = false;

		private const string ChronicleRefreshDisabledText = "Chronicle test\nRefresh disabled";

		private const string SagaRpcRequestFeed = "FehuChronicles_RequestFeed";

		private const string SagaRpcFeed = "FehuChronicles_Feed";

		private string _sagaChronicleText;

		private string _lastSagaLogSignature;

		private DateTime _lastSagaRpcRequestUtc = DateTime.MinValue;

		private DateTime _lastSagaFallbackReadUtc = DateTime.MinValue;

		private bool _sagaRpcRegistered;

		private bool _chronicleRefreshInProgress;

		private bool _chronicleWaitingForRpc;

		private DateTime _nextChronicleRefreshUtc = DateTime.MinValue;

		private DateTime _chronicleCycleStartedUtc = DateTime.MinValue;

		private int _chronicleGeneration;

		private int _chronicleActiveGeneration;

		private static readonly object[] EmptyRpcArgs = new object[0];

		private bool _runtimeSchedulersDisabledLogged;

		private static readonly FehuUiText DefaultFinalUiText = FehuUiText.CreateDefault();

		private static readonly FieldInfo CharacterSelectScreenField = FindFejdField("m_characterSelectScreen");

		private static readonly FieldInfo SettingsPopupField = FindFejdField("m_settingsPopup");

		private static readonly string[] FinalShortcutKeys = new string[10] { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10" };

		private static readonly string[] FinalActionIcons = new string[4] { "join.png", null, null, null };

		private static readonly string[] FinalHubIcons = new string[4] { "hub-codex.png", "hub-support.png", "hub-clanwarfare.png", "hub-modix.png" };

		private static readonly Color PrimarySilver = new Color(0.847f, 0.855f, 0.875f, 1f);

		private static readonly Color BrightSilver = new Color(0.894f, 0.902f, 0.918f, 1f);

		private static readonly Color SecondarySilver = new Color(0.749f, 0.765f, 0.788f, 1f);

		private static readonly Color TextShadow = new Color(0.045f, 0.05f, 0.06f, 0.9f);

		private bool _draggingSagaScrollbar;

		private float _sagaScrollbarDragOffset;

		private Texture2D _finalSupportIcon;

		private Texture2D _finalTileTexture;

		private Texture2D _finalTitleSeparator;

		private Texture2D _finalHubTexture;

		private Texture2D _finalPanelTexture;

		private GUIStyle _finalButtonStyle;

		private GUIStyle _finalHubTitleStyle;

		private Font _finalDisplayFont;

		private bool _finalFontResolved;

		private string _nativeMenuAction;

		private float _nativeActionEarliestRestoreTime;

		private bool _frontendServerPanelHidden;

		private static readonly FieldInfo SelectCharacterPanelField = FindFejdField("m_selectCharacterPanel");

		private static readonly FieldInfo NewCharacterPanelField = FindFejdField("m_newCharacterPanel");

		private static readonly FieldInfo[] FejdSubmenuFields = new FieldInfo[18]
		{
			FindFejdField("m_startGamePanel"),
			FindFejdField("m_selectCharacterPanel"),
			FindFejdField("m_newCharacterPanel"),
			FindFejdField("m_characterSelectScreen"),
			FindFejdField("m_serverListPanel"),
			FindFejdField("m_createWorldPanel"),
			FindFejdField("m_worldListPanel"),
			FindFejdField("m_settingsPopup"),
			FindFejdField("m_settingsPanel"),
			FindFejdField("m_creditsPanel"),
			FindFejdField("m_manageSavesMenu"),
			FindFejdField("m_addServerPanel"),
			FindFejdField("m_connectionFailedPanel"),
			FindFejdField("m_newGameVersionPanel"),
			FindFejdField("m_playerVersionPanel"),
			FindFejdField("m_worldVersionPanel"),
			FindFejdField("m_worldSourceInfoPanel"),
			FindFejdField("m_ndaPanel")
		};

		private readonly Dictionary<GameObject, Vector3> _mainMenuLogoOriginalScales = new Dictionary<GameObject, Vector3>();

		private readonly HashSet<GameObject> _mainMenuLogosHiddenByFehu = new HashSet<GameObject>();

		private static readonly FieldInfo NativeFavoritesField = typeof(ServerListGui).GetField("m_favoriteServersList", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo NativeFavoritesDirtyField = typeof(ServerListGui).GetField("m_filteredListOutdated", BindingFlags.Instance | BindingFlags.NonPublic);

		private bool _nativeFavoritesOpened;

		private static readonly FieldInfo StartGamePanelField = FindFejdField("m_startGamePanel");

		private RectTransform _movedWorldPanel;

		private Vector2 _originalWorldPanelPosition;

		private readonly Vector3[] _worldPanelCorners = (Vector3[])(object)new Vector3[4];

		private static readonly FieldInfo ConnectingDialogField = FindFejdField("m_connectingDialog");

		private static readonly FieldInfo LocalPlayerField = AccessTools.Field(typeof(Player), "m_localPlayer");

		private bool _landingVisible;

		private const int WorldDayTimeoutMilliseconds = 3500;

		private readonly Dictionary<string, Task<WorldDayResult>> _worldDayRequests = new Dictionary<string, Task<WorldDayResult>>(StringComparer.OrdinalIgnoreCase);

		private readonly List<HttpWebRequest> _worldDayWebRequests = new List<HttpWebRequest>();

		private readonly HashSet<string> _worldDayRendered = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private readonly WorldDayRefreshSchedule _worldDaySchedule = new WorldDayRefreshSchedule();

		private Stopwatch _worldDayClock;

		private int _worldDaySession;

		private bool _worldDayMenuActive;

		private bool _worldDayShutdown;

		private void Awake()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_0951: Unknown result type (might be due to invalid IL or missing references)
			//IL_0960: Expected O, but got Unknown
			//IL_095b: Unknown result type (might be due to invalid IL or missing references)
			//IL_096f: Expected O, but got Unknown
			if (IsolationI3MinimalShell)
			{
				if (!_isolationI3LoadedLogged)
				{
					Plugin.Log.LogInfo("[I3] Plugin loaded");
					Plugin.Log.LogInfo("[I3] Custom UI creation BYPASSED");
					Plugin.Log.LogInfo("[I3] Runtime systems DISABLED");
					Plugin.Log.LogInfo("[I3] No FehuLanding assets instantiated");
					_isolationI3LoadedLogged = true;
				}
				return;
			}
			ConfigFile runtimeConfig = Plugin.Instance.RuntimeConfig;
			bool flag = runtimeConfig.ContainsKey(new ConfigDefinition("Layout", "LayoutVersion"));
			_useAnchoredDefaultLayout = true;
			_layoutVersion = runtimeConfig.Bind<int>("Layout", "LayoutVersion", 7, "Internal schema version for the final approved mockup layout.");
			_resetLayout = runtimeConfig.Bind<bool>("Layout", "ResetLayout", false, "Set true once to restore all movable FehuLanding panels to their visible default positions.");
			_finalLeftOffsetX = runtimeConfig.Bind<int>("Layout", "LeftOffsetX", 0, "Saved horizontal offset for the unified left navigation column.");
			_finalLeftOffsetY = runtimeConfig.Bind<int>("Layout", "LeftOffsetY", 0, "Saved vertical offset for the unified left navigation column.");
			_finalRoadmapOffsetX = runtimeConfig.Bind<int>("Layout", "RoadmapOffsetX", 0, "Saved horizontal offset for Roadmap.");
			_finalRoadmapOffsetY = runtimeConfig.Bind<int>("Layout", "RoadmapOffsetY", 0, "Saved vertical offset for Roadmap.");
			_finalSagaOffsetX = runtimeConfig.Bind<int>("Layout", "SagaOffsetX", 0, "Saved horizontal offset for Saga Chronicles.");
			_finalSagaOffsetY = runtimeConfig.Bind<int>("Layout", "SagaOffsetY", 0, "Saved vertical offset for Saga Chronicles.");
			_finalHubOffsetX = runtimeConfig.Bind<int>("Layout", "HubOffsetX", 0, "Saved horizontal offset for the Forteca community hub.");
			_finalHubOffsetY = runtimeConfig.Bind<int>("Layout", "HubOffsetY", 0, "Saved vertical offset for the Forteca community hub.");
			_finalBottomBarOffsetX = runtimeConfig.Bind<int>("Layout", "BottomBarOffsetX", 0, "Saved horizontal offset for the bottom navigation bar.");
			_finalBottomBarOffsetY = runtimeConfig.Bind<int>("Layout", "BottomBarOffsetY", 0, "Saved vertical offset for the bottom navigation bar.");
			bool num = runtimeConfig.ContainsKey(new ConfigDefinition("Internal", "ConfigVersion"));
			_configVersion = runtimeConfig.Bind<int>("Internal", "ConfigVersion", 3, "Internal schema version for FehuLanding configuration migration.");
			BindCrashIsolation(runtimeConfig);
			LogCrashIsolationSettings();
			runtimeConfig.Remove(new ConfigDefinition("Fehu Social", "Title"));
			runtimeConfig.Save();
			_enabled = BindMigrated(runtimeConfig, "General", "Enabled", defaultValue: true, "Enable the FehuLanding main-menu interface.", "General", "EnableTheFehu");
			_showOnMainMenu = runtimeConfig.Bind<bool>("General", "ShowOnMainMenu", true, "Show the boards whenever the main menu opens.");
			_hideChangelog = BindMigrated(runtimeConfig, "Behavior", "HideVanillaChangelog", defaultValue: true, "Hide Valheim's changelog while FehuLanding is active.", "Vanilla Menu", "HideChangelog");
			_hideMerchStore = BindMigrated(runtimeConfig, "Behavior", "HideVanillaMerchStore", defaultValue: true, "Hide Valheim's Merch Store element while FehuLanding is active.", "Vanilla Menu", "HideMerchStore");
			_hideVersionText = BindMigrated(runtimeConfig, "Behavior", "HideValheimVersion", defaultValue: true, "Hide the vanilla version label behind the final FehuLanding navigation.", "Vanilla Menu", "HideVersionText");
			_hideModdedWarningText = BindMigrated(runtimeConfig, "Behavior", "HideVanillaModdedWarning", defaultValue: true, "Hide the vanilla modded-game information block.", "Vanilla Menu", "HideModdedWarningText");
			_hideShowLogButton = BindMigrated(runtimeConfig, "Behavior", "HideShowPlayerLog", defaultValue: true, "Hide Valheim's white Show Player.log proxy; FehuLanding keeps its own Player Log button.", "Vanilla Menu", "HideShowLogButton");
			if (!num || _configVersion.Value < 3)
			{
				_hideVersionText.Value = true;
				_hideShowLogButton.Value = true;
				_configVersion.Value = 3;
			}
			_enableLiveStatus = BindMigrated(runtimeConfig, "ServerStatus", "Enabled", defaultValue: true, "Enable native Steam live server status queries.", "ServerStatus", "EnableLiveStatus");
			_statusRefreshIntervalSeconds = BindMigrated(runtimeConfig, "ServerStatus", "RefreshSeconds", 60, "Refresh interval while Landing is visible.", "ServerStatus", "RefreshIntervalSeconds");
			_queryTimeoutMilliseconds = BindMigrated(runtimeConfig, "ServerStatus", "TimeoutMilliseconds", 1500, "Maximum time for one Steam query attempt.", "ServerStatus", "QueryTimeoutMilliseconds");
			_queryRetryCount = runtimeConfig.Bind<int>("ServerStatus", "RetryCount", 1, "Number of additional query-port candidate passes before a server is treated as offline.");
			_retryDelayMilliseconds = runtimeConfig.Bind<int>("ServerStatus", "RetryDelayMilliseconds", 250, "Short delay before status retry attempts.");
			_initialStaggerMilliseconds = runtimeConfig.Bind<int>("ServerStatus", "InitialStaggerMilliseconds", 50, "Small delay between starting each server query.");
			_pauseWhenLandingHidden = runtimeConfig.Bind<bool>("ServerStatus", "PauseWhenLandingHidden", true, "Do not run live polling while Landing is hidden.");
			_logOnlyStateChanges = runtimeConfig.Bind<bool>("ServerStatus", "LogOnlyStateChanges", true, "Log only live status state changes by default.");
			_debugStatusQueries = runtimeConfig.Bind<bool>("ServerStatus", "DebugStatusQueries", false, "Detailed query lifecycle diagnostics.");
			_enableLayoutDiagnostics = runtimeConfig.Bind<bool>("Diagnostics", "EnableLayoutDiagnostics", false, "Enable one-shot/rate-limited layout diagnostics. Disabled by default to prevent render-loop log spam.");
			_keepLastKnownStatusWhileChecking = runtimeConfig.Bind<bool>("ServerStatus", "KeepLastKnownStatusWhileChecking", true, "Keep green/red status visible while background refresh is checking.");
			_offlineConfirmationCycles = runtimeConfig.Bind<int>("ServerStatus", "OfflineConfirmationCycles", 2, "Failed query cycles required before showing Offline.");
			_onlineConfirmationCycles = runtimeConfig.Bind<int>("ServerStatus", "OnlineConfirmationCycles", 1, "Successful query cycles required before showing Online.");
			_showPlayerCounts = runtimeConfig.Bind<bool>("ServerStatus", "ShowPlayerCounts", true, "Show player counts after successful live status query.");
			_enableSteamIdIcons = runtimeConfig.Bind<bool>("ServerSteamIdIcons", "EnableSteamIdIcons", true, "Legacy compatibility setting. Realm-card lock icons are controlled only by FehuLanding.json steamIdIcon.");
			BindServerSteamIdIcons(runtimeConfig);
			_newsEnabled = BindMigrated(runtimeConfig, "Panels", "ShowRoadmap", defaultValue: true, "Show the Roadmap panel.", "News Board", "Enabled");
			_newsX = runtimeConfig.Bind<int>("News Board", "X", -20, (ConfigDescription)null);
			_newsY = runtimeConfig.Bind<int>("News Board", "Y", 70, (ConfigDescription)null);
			_newsWidth = runtimeConfig.Bind<int>("News Board", "Width", 460, (ConfigDescription)null);
			_newsHeight = runtimeConfig.Bind<int>("News Board", "Height", 475, (ConfigDescription)null);
			_newsTitle = runtimeConfig.Bind<string>("News Board", "Title", "Kingdoms - Roadmap", (ConfigDescription)null);
			_sagaEnabled = BindMigrated(runtimeConfig, "Panels", "ShowSaga", defaultValue: true, "Show the Saga Chronicles panel.", "Skald Saga Board", "Enabled");
			_sagaX = runtimeConfig.Bind<int>("Skald Saga Board", "X", -20, (ConfigDescription)null);
			_sagaY = runtimeConfig.Bind<int>("Skald Saga Board", "Y", -10, (ConfigDescription)null);
			_sagaWidth = runtimeConfig.Bind<int>("Skald Saga Board", "Width", 460, (ConfigDescription)null);
			_sagaHeight = runtimeConfig.Bind<int>("Skald Saga Board", "Height", 500, (ConfigDescription)null);
			_sagaTitle = runtimeConfig.Bind<string>("Skald Saga Board", "Title", "Saga Chronicles", (ConfigDescription)null);
			_realmsEnabled = BindMigrated(runtimeConfig, "Panels", "ShowFehuRealms", defaultValue: true, "Show the Fehu Realms panel.", "Realms Board", "Enabled");
			_rightX = runtimeConfig.Bind<int>("Realms Board", "X", 20, (ConfigDescription)null);
			_rightY = runtimeConfig.Bind<int>("Realms Board", "Y", 70, (ConfigDescription)null);
			_rightWidth = runtimeConfig.Bind<int>("Realms Board", "Width", 460, (ConfigDescription)null);
			_rightHeight = runtimeConfig.Bind<int>("Realms Board", "Height", 535, (ConfigDescription)null);
			_realmsTitle = runtimeConfig.Bind<string>("Realms Board", "Title", "Fehu Realms", (ConfigDescription)null);
			_otherRealmsEnabled = BindMigrated(runtimeConfig, "Panels", "ShowOtherRealms", defaultValue: true, "Show the Other Realms and native action panels.", "Other Realms Board", "Enabled");
			_otherX = runtimeConfig.Bind<int>("Other Realms Board", "X", 20, (ConfigDescription)null);
			_otherY = runtimeConfig.Bind<int>("Other Realms Board", "Y", -10, (ConfigDescription)null);
			_otherWidth = runtimeConfig.Bind<int>("Other Realms Board", "Width", 460, (ConfigDescription)null);
			_otherHeight = runtimeConfig.Bind<int>("Other Realms Board", "Height", 440, (ConfigDescription)null);
			_otherRealmsTitle = runtimeConfig.Bind<string>("Other Realms Board", "Title", "Other Realms", (ConfigDescription)null);
			_socialEnabled = BindMigrated(runtimeConfig, "Panels", "ShowHub", defaultValue: true, "Show the central Forteca hub.", "SocialPanel", "Enabled");
			_socialX = runtimeConfig.Bind<int>("SocialPanel", "X", -20, (ConfigDescription)null);
			_socialY = runtimeConfig.Bind<int>("SocialPanel", "Y", 10, (ConfigDescription)null);
			_socialWidth = runtimeConfig.Bind<int>("SocialPanel", "Width", 460, (ConfigDescription)null);
			_socialHeight = runtimeConfig.Bind<int>("SocialPanel", "Height", 80, (ConfigDescription)null);
			_socialIconSize = runtimeConfig.Bind<int>("SocialPanel", "SocialIconSize", 42, (ConfigDescription)null);
			_socialIconSpacing = runtimeConfig.Bind<int>("SocialPanel", "SocialIconSpacing", 8, (ConfigDescription)null);
			if (!IsolationI4StartupOnly)
			{
				Plugin.Log.LogInfo("[TheFehu] SocialPanel config applied X/Y/W/H/IconSize/IconSpacing");
			}
			_enablePanelDragging = runtimeConfig.Bind<bool>("General", "EnablePanelDragging", true, "Hold CTRL and drag FehuLanding panels to save their X/Y position.");
			BindMiniPanels(runtimeConfig);
			BindBottomLegend(runtimeConfig);
			InitializeShortcutLegendCaches();
			BindRealmLegend(runtimeConfig);
			MigrateOrResetLayout(runtimeConfig, (!flag) ? 1 : _layoutVersion.Value);
			if (_newsTitle.Value == "Announcements")
			{
				_newsTitle.Value = "Development Roadmap";
				runtimeConfig.Save();
			}
			_uiScale = BindMigrated(runtimeConfig, "Appearance", "UIScale", 1f, new ConfigDescription("Additional UI scale.", (AcceptableValueBase)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()), "General", "UIScale");
			RemoveObsoletePresentationConfig(runtimeConfig);
			runtimeConfig.Save();
			_contentPath = Path.Combine(Plugin.RuntimeDataPath, "FehuLanding.json");
			if (IsolationI4StartupOnly && !_isolationI4StartupLogged)
			{
				Plugin.Log.LogInfo("[I4] Config initialized");
			}
			LoadContent();
			if (IsolationI4StartupOnly && !_isolationI4StartupLogged)
			{
				Plugin.Log.LogInfo("[I4] JSON initialized");
			}
			if (IsolationI2StaticRuntime && !_isolationI2StartupLogged)
			{
				Plugin.Log.LogInfo("[I2] Static UI initialized");
				Plugin.Log.LogInfo("[I2] Background refresh DISABLED");
				Plugin.Log.LogInfo("[I2] AutoFit DISABLED");
				Plugin.Log.LogInfo("[I2] Runtime layout refresh DISABLED");
				_isolationI2StartupLogged = true;
			}
			SceneManager.sceneLoaded += OnSceneLoaded;
			if (IsolationI4StartupOnly && !_isolationI4StartupLogged)
			{
				Plugin.Log.LogInfo("[I4] Scene subscription initialized");
				Plugin.Log.LogInfo("[I4] Steam systems DISABLED");
				Plugin.Log.LogInfo("[I4] UI and assets BYPASSED");
				Plugin.Log.LogInfo("[I4] Runtime systems DISABLED");
				_isolationI4StartupLogged = true;
			}
		}

		private void OnDestroy()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			RestoreNativeWorldPanelPosition();
			if ((Object)(object)_activeLandingRoot == (Object)(object)this)
			{
				_activeLandingRoot = null;
			}
			RestoreMainMenuLogos();
			ShutdownWorldDayTelemetry();
			if ((Object)_activeLandingRoot != (Object)null && (Object)(object)_activeLandingRoot != (Object)(object)this)
			{
				Plugin.Log.LogWarning("[FehuLanding] Duplicate Landing root suppressed.");
				Object.Destroy((Object)((Component)this).gameObject);
				return;
			}
			_activeLandingRoot = this;
			if (IsolationI3MinimalShell)
			{
				if (!_isolationI3ShutdownLogged)
				{
					Plugin.Log.LogInfo("[I3] shutdown/disable reached");
					_isolationI3ShutdownLogged = true;
				}
				return;
			}
			_statusRuntimeAlive = false;
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (IsolationI4StartupOnly)
			{
				if (!_isolationI4ShutdownLogged)
				{
					Plugin.Log.LogInfo("[I4] shutdown/disable reached");
					_isolationI4ShutdownLogged = true;
				}
				return;
			}
			if (IsolationI1DisableNativeServerPolling && !_isolationI1ShutdownLogged)
			{
				Plugin.Log.LogInfo("[FehuLanding] I1 shutdown/disable reached");
				_isolationI1ShutdownLogged = true;
			}
			if (IsolationI2StaticRuntime && !_isolationI2ShutdownLogged)
			{
				Plugin.Log.LogInfo("[I2] shutdown/disable reached");
				_isolationI2ShutdownLogged = true;
			}
			if (CrashIsolationDiagnosticBuild)
			{
				DestroyIsolationOwnedObjects();
			}
			else
			{
				CancelAllServerQueries("destroy");
			}
		}

		private void BindCrashIsolation(ConfigFile config)
		{
			_isoUIRoot = config.Bind<bool>("Crash Isolation", "IsolationEnableUIRoot", false, (ConfigDescription)null);
			_isoMainPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableMainPanels", false, (ConfigDescription)null);
			_isoBottomPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableBottomPanels", false, (ConfigDescription)null);
			_isoServerPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableServerPanels", false, (ConfigDescription)null);
			_isoChronicleSaga = config.Bind<bool>("Crash Isolation", "IsolationEnableChronicleSaga", false, (ConfigDescription)null);
			_isoSocialShortcutPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableSocialShortcutPanels", false, (ConfigDescription)null);
			_isoClassicUiStyles = config.Bind<bool>("Crash Isolation", "IsolationEnableClassicUiStyles", false, (ConfigDescription)null);
			_isoIconsTexturesSprites = config.Bind<bool>("Crash Isolation", "IsolationEnableIconsTexturesSprites", false, (ConfigDescription)null);
			_isoLayoutSetup = config.Bind<bool>("Crash Isolation", "IsolationEnableLayoutSetup", false, (ConfigDescription)null);
			_isoSteam = config.Bind<bool>("Crash Isolation", "IsolationEnableSteam", false, (ConfigDescription)null);
			_isoRuntimeSystems = config.Bind<bool>("Crash Isolation", "IsolationEnableRuntimeSystems", false, (ConfigDescription)null);
		}

		private static bool Iso(ConfigEntry<bool> entry)
		{
			return entry?.Value ?? false;
		}

		private void LogCrashIsolationSettings()
		{
			if (CrashIsolationDiagnosticBuild && !_isolationSettingsLogged)
			{
				Plugin.Log.LogInfo("[Isolation] Diagnostic UI build active");
				Plugin.Log.LogInfo("[Isolation] UIRoot=" + Iso(_isoUIRoot));
				Plugin.Log.LogInfo("[Isolation] MainPanels=" + Iso(_isoMainPanels));
				Plugin.Log.LogInfo("[Isolation] BottomPanels=" + Iso(_isoBottomPanels));
				Plugin.Log.LogInfo("[Isolation] ServerPanels=" + Iso(_isoServerPanels));
				Plugin.Log.LogInfo("[Isolation] ChronicleSaga=" + Iso(_isoChronicleSaga));
				Plugin.Log.LogInfo("[Isolation] SocialShortcutPanels=" + Iso(_isoSocialShortcutPanels));
				Plugin.Log.LogInfo("[Isolation] ClassicUiStyles=" + Iso(_isoClassicUiStyles));
				Plugin.Log.LogInfo("[Isolation] IconsTexturesSprites=" + Iso(_isoIconsTexturesSprites));
				Plugin.Log.LogInfo("[Isolation] LayoutSetup=" + Iso(_isoLayoutSetup));
				Plugin.Log.LogInfo("[Isolation] Steam=" + Iso(_isoSteam));
				Plugin.Log.LogInfo("[Isolation] RuntimeSystems=" + Iso(_isoRuntimeSystems));
				_isolationSettingsLogged = true;
			}
		}

		private void BuildIsolationSceneOnce()
		{
			if (_isolationSceneBuilt)
			{
				if (!_isolationSceneSkipLogged)
				{
					Plugin.Log.LogInfo("[Isolation] Scene construction skipped; already initialized");
					_isolationSceneSkipLogged = true;
				}
			}
			else
			{
				_isolationSceneBuilt = true;
			}
		}

		private void DestroyIsolationOwnedObjects()
		{
			_isolationSceneBuilt = false;
		}

		private void LogIsolationWarningOnce(string key, string message)
		{
			if (_isolationGroupsLogged.Add("warn:" + key))
			{
				Plugin.Log.LogWarning(message);
			}
		}

		private void LogIsolationGroup(string groupName, Action action)
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			bool flag = false;
			bool flag2 = _isolationGroupsLogged.Add(groupName);
			if (flag2)
			{
				Plugin.Log.LogInfo("[Isolation] BEGIN " + groupName);
			}
			try
			{
				action?.Invoke();
				flag = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning("[Isolation] " + groupName + " failed: " + ex);
			}
			finally
			{
				stopwatch.Stop();
				if (flag2)
				{
					Plugin.Log.LogInfo("[Isolation] END " + groupName + " success=" + flag + " elapsedMs=" + stopwatch.ElapsedMilliseconds);
				}
			}
		}

		private void EnsureIsolationStyles()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_003c: Expected O, but got Unknown
			//IL_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			if (_isolationLabelStyle == null || _isolationBoxStyle == null)
			{
				_isolationLabelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					alignment = (TextAnchor)0,
					wordWrap = true
				};
				_isolationBoxStyle = new GUIStyle(GUI.skin.box)
				{
					fontSize = 14,
					alignment = (TextAnchor)4
				};
				_isolationGuiStylesCreated += 2;
				_isolationFontsResolved++;
			}
		}

		private void DrawCrashIsolationDiagnosticUi()
		{
			//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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsMainMenu() || !Iso(_isoUIRoot))
			{
				return;
			}
			if (_content == null)
			{
				LoadContent();
			}
			if (NeedsClassicUiBuild())
			{
				if (!Iso(_isoClassicUiStyles))
				{
					if (Iso(_isoMainPanels) || Iso(_isoBottomPanels) || Iso(_isoServerPanels) || Iso(_isoChronicleSaga) || Iso(_isoSocialShortcutPanels))
					{
						LogIsolationWarningOnce("ClassicUiStylesDependency", "[Isolation] Production visual groups bypassed because IsolationEnableClassicUiStyles=false");
					}
					return;
				}
				LogIsolationGroup("ClassicUiStyles", delegate
				{
					BuildClassicUi();
				});
			}
			float num = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * _uiScale.Value;
			num = Mathf.Max(0.35f, num);
			Matrix4x4 matrix = GUI.matrix;
			int depth = GUI.depth;
			GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
			GUI.depth = -1000;
			float num2 = (float)Screen.width / num;
			float logicalHeight = (float)Screen.height / num;
			if (Iso(_isoMainPanels) && _newsEnabled.Value && _topLeftVisible)
			{
				LogIsolationGroup("MainPanels", delegate
				{
					//IL_009e: Unknown result type (might be due to invalid IL or missing references)
					Rect panel = default(Rect);
					((Rect)(ref panel))..ctor((float)_newsX.Value, (float)_newsY.Value, (float)_newsWidth.Value, (float)_newsHeight.Value);
					if (Iso(_isoLayoutSetup))
					{
						HandlePanelDrag("TopLeft", ref panel, _newsX, _newsY, rightAnchored: false, num2, logicalHeight);
					}
					DrawStoryBoard("TopLeft", panel, string.IsNullOrEmpty(_newsTitle.Value) ? _content.newsTitle : _newsTitle.Value, _content.newsText, ref _newsScroll, ref _topLeftVisible);
				});
			}
			if (Iso(_isoChronicleSaga) && _sagaEnabled.Value && _bottomLeftVisible)
			{
				LogIsolationGroup("ChronicleSaga", delegate
				{
					//IL_009e: Unknown result type (might be due to invalid IL or missing references)
					Rect panel = default(Rect);
					((Rect)(ref panel))..ctor((float)_sagaX.Value, (float)_sagaY.Value, (float)_sagaWidth.Value, (float)_sagaHeight.Value);
					if (Iso(_isoLayoutSetup))
					{
						HandlePanelDrag("BottomLeft", ref panel, _sagaX, _sagaY, rightAnchored: false, num2, logicalHeight);
					}
					DrawChronicleBoard("BottomLeft", panel, string.IsNullOrEmpty(_sagaTitle.Value) ? _content.sagaTitle : _sagaTitle.Value, ref _sagaScroll, ref _bottomLeftVisible);
				});
			}
			if (Iso(_isoServerPanels))
			{
				LogIsolationGroup("ServerPanels", delegate
				{
					//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
					//IL_020e: Unknown result type (might be due to invalid IL or missing references)
					if (_realmsEnabled.Value && _topRightVisible)
					{
						Rect panel = default(Rect);
						((Rect)(ref panel))..ctor(num2 - (float)_rightWidth.Value + (float)_rightX.Value, (float)_rightY.Value, (float)_rightWidth.Value, (float)_rightHeight.Value);
						if (Iso(_isoLayoutSetup))
						{
							HandlePanelDrag("TopRight", ref panel, _rightX, _rightY, rightAnchored: true, num2, logicalHeight);
						}
						DrawRealmsBoard("TopRight", panel, string.IsNullOrEmpty(_realmsTitle.Value) ? _content.realmsTitle : _realmsTitle.Value, _fehuRealmServers, ref _topRightVisible, fehuRealm: true);
					}
					if (_otherRealmsEnabled.Value && _bottomRightVisible)
					{
						Rect panel2 = default(Rect);
						((Rect)(ref panel2))..ctor(num2 - (float)_otherWidth.Value + (float)_otherX.Value, (float)_otherY.Value, (float)_otherWidth.Value, (float)_otherHeight.Value);
						if (Iso(_isoLayoutSetup))
						{
							HandlePanelDrag("BottomRight", ref panel2, _otherX, _otherY, rightAnchored: true, num2, logicalHeight);
						}
						DrawRealmsBoard("BottomRight", panel2, _otherRealmsTitle.Value, _otherRealmServers, ref _bottomRightVisible, fehuRealm: false);
					}
				});
			}
			if (Iso(_isoSocialShortcutPanels))
			{
				LogIsolationGroup("SocialShortcutPanels", delegate
				{
					//IL_013b: Unknown result type (might be due to invalid IL or missing references)
					SocialPanelSettings socialPanelSettings = new SocialPanelSettings
					{
						Enabled = _socialEnabled.Value,
						X = _socialX.Value,
						Y = _socialY.Value,
						Width = _socialWidth.Value,
						Height = _socialHeight.Value,
						IconSize = _socialIconSize.Value,
						IconSpacing = _socialIconSpacing.Value
					};
					if (socialPanelSettings.Enabled && _socialVisible)
					{
						Rect panel = default(Rect);
						((Rect)(ref panel))..ctor(num2 - (float)socialPanelSettings.Width + (float)socialPanelSettings.X, (float)socialPanelSettings.Y, (float)socialPanelSettings.Width, (float)socialPanelSettings.Height);
						if (Iso(_isoLayoutSetup))
						{
							HandlePanelDrag("Social", ref panel, _socialX, _socialY, rightAnchored: true, num2, logicalHeight);
						}
						DrawSocial(panel, socialPanelSettings);
					}
					DrawMiniPanels(num2, logicalHeight);
				});
			}
			if (Iso(_isoBottomPanels))
			{
				LogIsolationGroup("BottomPanels", delegate
				{
					DrawBottomLegend(num2, logicalHeight);
				});
			}
			GUI.matrix = matrix;
			GUI.depth = depth;
			if (!_isolationAssetTotalsLogged)
			{
				Plugin.Log.LogInfo("[Isolation Assets] Texture2D created=" + _isolationTexturesCreated);
				Plugin.Log.LogInfo("[Isolation Assets] Sprites created=" + _isolationSpritesCreated);
				Plugin.Log.LogInfo("[Isolation Assets] Fonts resolved=" + _isolationFontsResolved);
				Plugin.Log.LogInfo("[Isolation Assets] GUIStyles created=" + _isolationGuiStylesCreated);
				_isolationAssetTotalsLogged = true;
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (!IsolationI3MinimalShell && !IsolationI4StartupOnly)
			{
				RefreshLandingVisibility();
			}
		}

		private IEnumerator MerchDiscoveryAfterLoad()
		{
			yield return (object)new WaitForSeconds(1f);
			LogMerchCandidates();
		}

		private IEnumerator HideVanillaMenuAfterLoad()
		{
			HideVanillaMenu();
			yield return (object)new WaitForSeconds(0.5f);
			HideVanillaMenu();
			yield return (object)new WaitForSeconds(0.5f);
			HideVanillaMenu();
			yield return (object)new WaitForSeconds(2f);
			HideVanillaMenu();
			yield return (object)new WaitForSeconds(2f);
			HideVanillaMenu();
		}

		private void Update()
		{
			if (IsolationI3MinimalShell || IsolationI4StartupOnly || (CrashIsolationDiagnosticBuild && !Iso(_isoRuntimeSystems)))
			{
				return;
			}
			RefreshLandingVisibility();
			if (Input.GetKeyDown((KeyCode)291) && (_landingVisible || (IsFrontendServerPanelVisible() && !_frontendServerPanelHidden)))
			{
				ExecuteFinalShortcut(9, "keyboard");
				if (_hiddenForSession && (_pauseWhenLandingHidden == null || _pauseWhenLandingHidden.Value))
				{
					CancelAllServerQueries("landing hidden");
				}
			}
			UpdateNativeMenuActionVisibility();
			UpdateMainMenuLogoVisibility();
			if (DisableAllRuntimeSchedulersIsolation)
			{
				if (!_runtimeSchedulersDisabledLogged)
				{
					Plugin.Log.LogInfo("[Isolation] Runtime schedulers disabled.");
					_runtimeSchedulersDisabledLogged = true;
				}
			}
			else if (_landingVisible)
			{
				if (IsolationI2StaticRuntime)
				{
					if (!_isolationI2RuntimeLogged)
					{
						Plugin.Log.LogInfo("[I2] Runtime background refresh suppressed");
						_isolationI2RuntimeLogged = true;
					}
					return;
				}
				UpdateWorldDayTelemetry();
				if (_hiddenForSession && (_pauseWhenLandingHidden == null || _pauseWhenLandingHidden.Value))
				{
					CancelAllServerQueries("landing hidden");
				}
				else
				{
					BeginServerQueriesIfNeeded();
					if (!IsolationI1DisableNativeServerPolling)
					{
						CheckActiveServerQueryTimeout();
						PumpSteamServerQuery();
					}
				}
				if (!DisableChronicleRefreshIsolation)
				{
					RunChronicleScheduler();
				}
			}
			else if (IsFrontendServerPanelVisible())
			{
				UpdateWorldDayTelemetry();
				BeginServerQueriesIfNeeded();
				if (!IsolationI1DisableNativeServerPolling)
				{
					CheckActiveServerQueryTimeout();
					PumpSteamServerQuery();
				}
			}
			else if (_serverQueriesRunning || _activeServerQueries.Count > 0)
			{
				CancelAllServerQueries("left main menu");
			}
		}

		private void OnGUI()
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			RefreshLandingVisibility();
			if (IsolationI3MinimalShell || IsolationI4StartupOnly)
			{
				return;
			}
			if (CrashIsolationDiagnosticBuild)
			{
				DrawCrashIsolationDiagnosticUi();
			}
			else if (_enabled.Value && _showOnMainMenu.Value && ((!_hiddenForSession && _landingVisible) || (IsFrontendServerPanelVisible() && !_frontendServerPanelHidden)))
			{
				if (_content == null)
				{
					LoadContent();
				}
				if (_titleStyle == null)
				{
					BuildClassicUi();
					BlockMerchStoreClickOnce();
				}
				float num = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * _uiScale.Value;
				num = Mathf.Max(0.35f, num);
				Matrix4x4 matrix = GUI.matrix;
				int depth = GUI.depth;
				GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
				GUI.depth = -1000;
				float logicalWidth = (float)Screen.width / num;
				float logicalHeight = (float)Screen.height / num;
				DrawFinalApprovedLayout(logicalWidth, logicalHeight);
				GUI.matrix = matrix;
				GUI.depth = depth;
			}
		}

		private string GetSagaChronicleText()
		{
			if (DisableChronicleRefreshIsolation)
			{
				return "Chronicle test\nRefresh disabled";
			}
			if (!string.IsNullOrWhiteSpace(_sagaChronicleText))
			{
				return _sagaChronicleText;
			}
			return _content.sagaText;
		}

		private void RunChronicleScheduler()
		{
			TryRegisterSagaRpc();
			DateTime utcNow = DateTime.UtcNow;
			if (_chronicleRefreshInProgress)
			{
				if (_chronicleWaitingForRpc && (utcNow - _chronicleCycleStartedUtc).TotalSeconds >= 2.0)
				{
					ReadSagaFeedFallbackOnce();
					FinishChronicleRefresh("fallback-after-rpc-timeout");
				}
				else if ((utcNow - _chronicleCycleStartedUtc).TotalSeconds >= 5.0)
				{
					FinishChronicleRefresh("timeout");
				}
			}
			else if (!(utcNow < _nextChronicleRefreshUtc))
			{
				StartChronicleRefreshCycle();
			}
		}

		private void StartChronicleRefreshCycle()
		{
			_chronicleRefreshInProgress = true;
			_chronicleWaitingForRpc = false;
			_chronicleCycleStartedUtc = DateTime.UtcNow;
			_chronicleGeneration++;
			_chronicleActiveGeneration = _chronicleGeneration;
			Plugin.Log.LogInfo("[FehuLanding] Chronicle refresh started");
			if (_sagaRpcRegistered && ZRoutedRpc.instance != null)
			{
				try
				{
					_lastSagaRpcRequestUtc = DateTime.UtcNow;
					_chronicleWaitingForRpc = true;
					ZRoutedRpc.instance.InvokeRoutedRPC("FehuChronicles_RequestFeed", EmptyRpcArgs);
					return;
				}
				catch (Exception ex)
				{
					LogChronicleRefreshFailure("RPC request unavailable: " + ex.Message);
				}
			}
			ReadSagaFeedFallbackOnce();
			FinishChronicleRefresh("fallback");
		}

		private void FinishChronicleRefresh(string reason)
		{
			_chronicleRefreshInProgress = false;
			_chronicleWaitingForRpc = false;
			_nextChronicleRefreshUtc = DateTime.UtcNow.AddSeconds(30.0);
			Plugin.Log.LogInfo("[FehuLanding] Chronicle refresh completed: " + reason);
		}

		private void TryRegisterSagaRpc()
		{
			if (_sagaRpcRegistered || ZRoutedRpc.instance == null)
			{
				return;
			}
			try
			{
				ZRoutedRpc.instance.Register<string>("FehuChronicles_Feed", (Action<long, string>)OnSagaFeedRpc);
				_sagaRpcRegistered = true;
				Plugin.Log.LogInfo("[FehuLanding] SkaldSaga RPC receiver registered: FehuChronicles_Feed");
			}
			catch (Exception ex)
			{
				LogChronicleRefreshFailure("RPC receiver failed: " + ex.Message);
			}
		}

		private void RequestSagaFeedIfNeeded()
		{
			if (!_chronicleRefreshInProgress)
			{
				StartChronicleRefreshCycle();
			}
		}

		private void OnSagaFeedRpc(long sender, string json)
		{
			if (!DisableChronicleRefreshIsolation)
			{
				if (!_chronicleRefreshInProgress || !_chronicleWaitingForRpc)
				{
					Plugin.Log.LogInfo("[FehuLanding] Chronicle stale RPC response ignored");
					return;
				}
				ApplySagaFeedJson(json, 10);
				FinishChronicleRefresh("rpc");
			}
		}

		private void ReadSagaFeedFallbackIfNeeded()
		{
			if (!_chronicleRefreshInProgress)
			{
				StartChronicleRefreshCycle();
			}
		}

		private void ReadSagaFeedFallbackOnce()
		{
			_lastSagaFallbackReadUtc = DateTime.UtcNow;
			try
			{
				string path = Path.Combine(Plugin.RuntimeDataPath, "SagaFeed.json");
				if (File.Exists(path))
				{
					ApplySagaFeedJson(File.ReadAllText(path), 10);
				}
			}
			catch (Exception ex)
			{
				LogChronicleRefreshFailure("SagaFeed fallback failed: " + ex.Message);
			}
		}

		private bool ApplySagaFeedJson(string json, int maxEntries)
		{
			List<SagaFeedEntry> list = ParseSagaFeedEntries(json, maxEntries);
			if (list.Count == 0)
			{
				return false;
			}
			_chronicleEntries.Clear();
			_chronicleEntries.AddRange(list);
			ApplySagaChronicleText(BuildSagaPlainText(list));
			return true;
		}

		private void ApplySagaChronicleText(string text)
		{
			if (!string.IsNullOrWhiteSpace(text))
			{
				_sagaChronicleText = text;
				LogSagaTextLoaded(text);
			}
		}

		private void LogChronicleRefreshFailure(string message)
		{
			Plugin.Log.LogWarning("[FehuLanding] Chronicle refresh failed: " + message);
		}

		private void LogSagaTextLoaded(string text)
		{
			if (!string.IsNullOrWhiteSpace(text))
			{
				int num = text.Split(new char[1] { '\n' }).Length;
				string text2 = num + ":" + text.Length;
				if (!(_lastSagaLogSignature == text2))
				{
					_lastSagaLogSignature = text2;
					Plugin.Log.LogInfo("[FehuLanding] Saga text loaded: " + num + " lines");
				}
			}
		}

		private static string NormalizeChronicleText(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return value;
			}
			List<string> list = new List<string>();
			bool flag = false;
			string[] array = value.Replace("\r\n", "\n").Replace('\r', '\n').Split(new char[1] { '\n' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].TrimEnd(Array.Empty<char>());
				if (string.IsNullOrWhiteSpace(text))
				{
					if (!flag && list.Count > 0)
					{
						list.Add(string.Empty);
						flag = true;
					}
				}
				else
				{
					list.Add(text);
					flag = false;
				}
			}
			while (list.Count > 0 && string.IsNullOrWhiteSpace(list[list.Count - 1]))
			{
				list.RemoveAt(list.Count - 1);
			}
			return string.Join("\n", list.ToArray());
		}

		private static string FormatSagaFeed(string json, int maxEntries)
		{
			List<SagaFeedEntry> list = ParseSagaFeedEntries(json, maxEntries);
			if (list.Count == 0)
			{
				return null;
			}
			return BuildSagaPlainText(list);
		}

		private static List<SagaFeedEntry> ParseSagaFeedEntries(string json, int maxEntries)
		{
			List<SagaFeedEntry> list = new List<SagaFeedEntry>();
			if (string.IsNullOrWhiteSpace(json))
			{
				return list;
			}
			foreach (Match item in Regex.Matches(json, "\\{(?<entry>[^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}"))
			{
				string value = item.Groups["entry"].Value;
				if (value.Contains("\"title\""))
				{
					SagaFeedEntry sagaFeedEntry = new SagaFeedEntry
					{
						TimestampUtc = ReadSagaDate(value, "timestampUtc"),
						RealmDisplayName = ReadSagaString(value, "realmDisplayName"),
						Category = ReadSagaString(value, "category"),
						Title = ReadSagaString(value, "title"),
						Text = ReadSagaString(value, "text"),
						Priority = ReadSagaString(value, "priority")
					};
					if (sagaFeedEntry.TimestampUtc == DateTime.MinValue)
					{
						sagaFeedEntry.TimestampUtc = ReadSagaDate(value, "timestampUTC");
					}
					if (sagaFeedEntry.TimestampUtc == DateTime.MinValue)
					{
						sagaFeedEntry.TimestampUtc = ReadSagaDate(value, "timestamp");
					}
					if (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName))
					{
						sagaFeedEntry.RealmDisplayName = ReadSagaString(value, "server");
					}
					if (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName))
					{
						sagaFeedEntry.RealmDisplayName = ReadSagaString(value, "serverName");
					}
					if (string.IsNullOrWhiteSpace(sagaFeedEntry.Category))
					{
						sagaFeedEntry.Category = ReadSagaString(value, "eventType");
					}
					if (string.IsNullOrWhiteSpace(sagaFeedEntry.Priority))
					{
						sagaFeedEntry.Priority = ReadSagaString(value, "importance");
					}
					sagaFeedEntry.RealmDisplayName = (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName) ? "Fehu Realms" : sagaFeedEntry.RealmDisplayName.Trim());
					sagaFeedEntry.Category = NormalizeChronicleCategory(sagaFeedEntry.Category);
					sagaFeedEntry.Priority = NormalizeChroniclePriority(sagaFeedEntry.Priority);
					sagaFeedEntry.Title = (string.IsNullOrWhiteSpace(sagaFeedEntry.Title) ? "Chronicle" : sagaFeedEntry.Title.Trim());
					sagaFeedEntry.Text = (sagaFeedEntry.Text ?? string.Empty).Trim();
					list.Add(sagaFeedEntry);
				}
			}
			if (list.Count == 0)
			{
				return list;
			}
			list.Sort((SagaFeedEntry a, SagaFeedEntry b) => b.TimestampUtc.CompareTo(a.TimestampUtc));
			int num = Mathf.Max(1, maxEntries);
			if (list.Count > num)
			{
				list.RemoveRange(num, list.Count - num);
			}
			return list;
		}

		private static string BuildSagaPlainText(List<SagaFeedEntry> entries)
		{
			if (entries == null || entries.Count == 0)
			{
				return null;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < entries.Count; i++)
			{
				SagaFeedEntry sagaFeedEntry = entries[i];
				list.Add("[" + sagaFeedEntry.RealmDisplayName + "] [" + sagaFeedEntry.Category + "]");
				list.Add(sagaFeedEntry.Title);
				if (!string.IsNullOrWhiteSpace(sagaFeedEntry.Text))
				{
					list.Add(sagaFeedEntry.Text);
				}
				list.Add(string.Empty);
			}
			return string.Join("\n", list.ToArray()).TrimEnd(Array.Empty<char>());
		}

		private static string NormalizeChronicleCategory(string value)
		{
			string text = (value ?? string.Empty).Trim().ToUpperInvariant();
			switch (text)
			{
			case "CLAN":
			case "LORE":
			case "ADMIN":
			case "EVENT":
			case "QUEST":
			case "PLAYER":
			case "SYSTEM":
			case "MARKET":
			case "SERVER":
			case "WAR":
			case "TERRITORY":
			case "KINGDOM":
				return text;
			default:
				return "LORE";
			}
		}

		private static string NormalizeChroniclePriority(string value)
		{
			string text = (value ?? string.Empty).Trim().ToUpperInvariant();
			if (text == "CRITICAL" || text == "IMPORTANT")
			{
				return text;
			}
			return "NORMAL";
		}

		private static string ReadSagaString(string block, string name)
		{
			Match match = Regex.Match(block, "\\\"" + Regex.Escape(name) + "\\\"\\s*:\\s*\\\"(?<v>(?:\\\\.|[^\\\"])*)\\\"");
			if (!match.Success)
			{
				return string.Empty;
			}
			return match.Groups["v"].Value.Replace("\\n", "\n").Replace("\\\"", "\"").Replace("\\\\", "\\");
		}

		private static DateTime ReadSagaDate(string block, string name)
		{
			if (!DateTime.TryParse(ReadSagaString(block, name), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out var result))
			{
				return DateTime.MinValue;
			}
			return result.ToUniversalTime();
		}

		private void SetAllMiniVisible(bool visible)
		{
			for (int i = 0; i < _miniVisible.Length; i++)
			{
				_miniVisible[i] = visible;
			}
		}

		private void BindServerSteamIdIcons(ConfigFile config)
		{
			_serverSteamIdIconEntries.Clear();
			BindServerSteamIdIcon(config, "10thWorld", defaultValue: false);
			BindServerSteamIdIcon(config, "Adventure", defaultValue: true);
			BindServerSteamIdIcon(config, "Immersive", defaultValue: true);
			BindServerSteamIdIcon(config, "Conquest", defaultValue: false);
			BindServerSteamIdIcon(config, "Dominion", defaultValue: false);
			BindServerSteamIdIcon(config, "BuildHeim", defaultValue: true);
			BindServerSteamIdIcon(config, "Blackheim", defaultValue: true);
			BindServerSteamIdIcon(config, "Warheim", defaultValue: false);
			BindServerSteamIdIcon(config, "FortecaTest", defaultValue: true);
			BindServerSteamIdIcon(config, "Vanilla", defaultValue: false);
		}

		private void BindServerSteamIdIcon(ConfigFile config, string key, bool defaultValue)
		{
			_serverSteamIdIconEntries[key] = config.Bind<bool>("ServerSteamIdIcons", key, defaultValue, "Legacy compatibility setting. Realm-card lock icons are controlled only by FehuLanding.json steamIdIcon.");
		}

		private bool ShouldShowSteamIdIcon(FehuServer server)
		{
			return server?.steamIdIcon ?? false;
		}

		private static string ServerSteamIdConfigKey(string serverId, string serverName)
		{
			string text = Regex.Replace(serverId ?? string.Empty, "[^A-Za-z0-9]", string.Empty).ToLowerInvariant();
			if (!string.IsNullOrEmpty(text))
			{
				switch (text)
				{
				case "buildheim":
					return "BuildHeim";
				case "blackheim":
					return "Blackheim";
				case "warheim":
					return "Warheim";
				case "fortecatest":
					return "FortecaTest";
				case "vanilla":
					return "Vanilla";
				}
			}
			string text2 = Regex.Replace(serverName ?? string.Empty, "[^A-Za-z0-9]", string.Empty).ToLowerInvariant();
			switch (text2)
			{
			case "10thworld":
			case "fehu10thworld":
				return "10thWorld";
			case "adventure":
			case "fehuadventure":
				return "Adventure";
			case "immersive":
			case "fehuimmersive":
				return "Immersive";
			case "conquest":
			case "fehuconquest":
				return "Conquest";
			case "dominion":
			case "fehudominion":
				return "Dominion";
			case "buildheim":
				return "BuildHeim";
			case "blackheim":
				return "Blackheim";
			case "warheim":
				return "Warheim";
			case "fortecatest":
				return "FortecaTest";
			case "vanilla":
				return "Vanilla";
			default:
				return text2;
			}
		}

		private void BindMiniPanels(ConfigFile config)
		{
			_miniEnabled = new ConfigEntry<bool>[3];
			_miniX = new ConfigEntry<int>[3];
			_miniY = new ConfigEntry<int>[3];
			_miniWidth = new ConfigEntry<int>[3];
			_miniHeight = new ConfigEntry<int>[3];
			_miniText = new ConfigEntry<string>[3];
			_miniIcons = new ConfigEntry<string>[3];
			_miniUrl = new ConfigEntry<string>[3];
			MiniPanelSettings[] array = new MiniPanelSettings[3]
			{
				new MiniPanelSettings
				{
					Enabled = true,
					X = 20,
					Y = 5,
					Width = 460,
					Height = 80,
					Text = "Forteca",
					Icons = "1fehu.png,2fehu.png,3fehu.png,4fehu.png",
					Url = string.Empty
				},
				new MiniPanelSettings
				{
					Enabled = true,
					X = 20,
					Y = -98,
					Width = 460,
					Height = 80,
					Text = "Press F7 to close all tabs.",
					Icons = string.Empty,
					Url = string.Empty
				},
				new MiniPanelSettings
				{
					Enabled = true,
					X = -20,
					Y = -98,
					Width = 460,
					Height = 80,
					Text = "BLACK VIKING",
					Icons = string.Empty,
					Url = string.Empty
				}
			};
			for (int i = 0; i < array.Length; i++)
			{
				string text = "MiniPanel" + (i + 1);
				_miniEnabled[i] = config.Bind<bool>(text, "Enabled", array[i].Enabled, (ConfigDescription)null);
				_miniX[i] = config.Bind<int>(text, "X", array[i].X, (ConfigDescription)null);
				_miniY[i] = config.Bind<int>(text, "Y", array[i].Y, (ConfigDescription)null);
				_miniWidth[i] = config.Bind<int>(text, "Width", array[i].Width, (ConfigDescription)null);
				_miniHeight[i] = config.Bind<int>(text, "Height", array[i].Height, (ConfigDescription)null);
				_miniText[i] = config.Bind<string>(text, "Text", array[i].Text, (ConfigDescription)null);
				_miniIcons[i] = config.Bind<string>(text, "Icons", array[i].Icons, (ConfigDescription)null);
				_miniUrl[i] = config.Bind<string>(text, "Url", array[i].Url, (ConfigDescription)null);
			}
		}

		private void BindBottomLegend(ConfigFile config)
		{
			_bottomLegendEnabled = config.Bind<bool>("Panels", "ShowBottomBar", true, "Show the Player Log, F1-F10 and Leaderboard bar.");
			_leftLegendEnabled = config.Bind<bool>("BottomLegend", "LeftPanelEnabled", true, (ConfigDescription)null);
			_rightLegendEnabled = config.Bind<bool>("BottomLegend", "RightPanelEnabled", true, (ConfigDescription)null);
			_bottomLeftLegendX = config.Bind<int>("BottomLegend", "BottomLeftPanelX", 20, (ConfigDescription)null);
			_bottomLeftLegendY = config.Bind<int>("BottomLegend", "BottomLeftPanelY", -98, (ConfigDescription)null);
			_bottomRightLegendX = config.Bind<int>("BottomLegend", "BottomRightPanelX", -20, (ConfigDescription)null);
			_bottomRightLegendY = config.Bind<int>("BottomLegend", "BottomRightPanelY", -98, (ConfigDescription)null);
			_legendF1Enabled = config.Bind<bool>("BottomLegend", "F1Enabled", true, (ConfigDescription)null);
			_legendF1Label = config.Bind<string>("BottomLegend", "F1Label", "Configs", (ConfigDescription)null);
			_legendF3Enabled = config.Bind<bool>("BottomLegend", "F3Enabled", true, (ConfigDescription)null);
			_legendF3Label = config.Bind<string>("BottomLegend", "F3Label", "Clan Warfare", (ConfigDescription)null);
			_legendF4Enabled = config.Bind<bool>("BottomLegend", "F4Enabled", true, (ConfigDescription)null);
			_legendF4Label = config.Bind<string>("BottomLegend", "F4Label", "Vault", (ConfigDescription)null);
			_legendF6Enabled = config.Bind<bool>("BottomLegend", "F6Enabled", true, (ConfigDescription)null);
			_legendF6Label = config.Bind<string>("BottomLegend", "F6Label", "Rumble", (ConfigDescription)null);
			_legendF7Enabled = config.Bind<bool>("BottomLegend", "F7Enabled", true, (ConfigDescription)null);
			_legendF7Label = config.Bind<string>("BottomLegend", "F7Label", "Landing", (ConfigDescription)null);
			_legendF8Enabled = config.Bind<bool>("BottomLegend", "F8Enabled", true, (ConfigDescription)null);
			_legendF8Label = config.Bind<string>("BottomLegend", "F8Label", "HERALDRY", (ConfigDescription)null);
			_legendF9Enabled = config.Bind<bool>("BottomLegend", "F9Enabled", true, (ConfigDescription)null);
			_legendF9Label = config.Bind<string>("BottomLegend", "F9Label", "Rewards", (ConfigDescription)null);
			_legendF10Enabled = config.Bind<bool>("BottomLegend", "F10Enabled", true, (ConfigDescription)null);
			_legendF10Label = config.Bind<string>("BottomLegend", "F10Label", "Choose Race", (ConfigDescription)null);
			_steamIdLegendEnabled = config.Bind<bool>("BottomLegend", "SteamIdLegendEnabled", true, (ConfigDescription)null);
			_steamIdLegendLabel = config.Bind<string>("BottomLegend", "SteamIdLegendLabel", "SteamID Protected Realm", (ConfigDescription)null);
		}

		private void BindRealmLegend(ConfigFile config)
		{
			_steamIdLegendEnabled = config.Bind<bool>("RealmLegend", "ShowSteamIdLegend", true, (ConfigDescription)null);
			_joinLegendEnabled = config.Bind<bool>("RealmLegend", "ShowJoinLegend", true, (ConfigDescription)null);
			_steamIdLegendLabel = config.Bind<string>("RealmLegend", "SteamIdTitle", "SteamID Protected Realm", (ConfigDescription)null);
			_steamIdLegendText = config.Bind<string>("RealmLegend", "SteamIdText", "Become a Supporter or Contributor\nto gain access.", (ConfigDescription)null);
			_joinLegendTitle = config.Bind<string>("RealmLegend", "JoinTitle", "Join a Realm", (ConfigDescription)null);
			_joinLegendText = config.Bind<string>("RealmLegend", "JoinText", "Click the open gate to join.", (ConfigDescription)null);
		}

		private void MigrateOrResetLayout(ConfigFile config, int previousLayoutVersion)
		{
			if (_resetLayout.Value || previousLayoutVersion < 6)
			{
				ApplyCanonicalLayoutDefaults();
				_resetLayout.Value = false;
				_layoutVersion.Value = 7;
				config.Save();
				Plugin.Log.LogInfo("[FehuLanding] Layout migrated/reset to unified navigation schema v7.");
				return;
			}
			if (previousLayoutVersion < 7)
			{
				_finalBottomBarOffsetX.Value = 0;
				_finalBottomBarOffsetY.Value = 0;
				Plugin.Log.LogInfo("[FehuLanding] Bottom navigation drag position initialized for layout schema v7.");
			}
			_layoutVersion.Value = 7;
			config.Save();
		}

		private static ConfigEntry<T> BindMigrated<T>(ConfigFile config, string section, string key, T defaultValue, string description, string legacySection, string legacyKey)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			return BindMigrated(config, section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), legacySection, legacyKey);
		}

		private static ConfigEntry<T> BindMigrated<T>(ConfigFile config, string section, string key, T defaultValue, ConfigDescription description, string legacySection, string legacyKey)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			ConfigDefinition val2 = new ConfigDefinition(legacySection, legacyKey);
			T val3 = defaultValue;
			if (!config.ContainsKey(val) && config.ContainsKey(val2))
			{
				val3 = config.Bind<T>(legacySection, legacyKey, defaultValue, (ConfigDescription)null).Value;
			}
			ConfigEntry<T> result = config.Bind<T>(section, key, val3, description);
			config.Remove(val2);
			return result;
		}

		private static void RemoveObsoletePresentationConfig(ConfigFile config)
		{
			string[] obsoleteSections = new string[16]
			{
				"News Board", "Skald Saga Board", "Realms Board", "Other Realms Board", "SocialPanel", "ServerSteamIdIcons", "RealmLegend", "BottomLegend", "MiniPanel 1", "MiniPanel 2",
				"MiniPanel 3", "MiniPanel1", "MiniPanel2", "MiniPanel3", "Crash Isolation", "Vanilla Menu"
			};
			List<ConfigDefinition> list = new List<ConfigDefinition>();
			foreach (ConfigDefinition key in config.Keys)
			{
				if (IsObsoleteConfigSection(key.Section, obsoleteSections) || IsObsoleteThemeConfig(key))
				{
					list.Add(key);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				config.Remove(list[i]);
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(ConfigFile), "<OrphanedEntries>k__BackingField");
			Dictionary<ConfigDefinition, string> dictionary = ((fieldInfo != null) ? (fieldInfo.GetValue(config) as Dictionary<ConfigDefinition, string>) : null);
			if (dictionary == null)
			{
				return;
			}
			list.Clear();
			foreach (ConfigDefinition key2 in dictionary.Keys)
			{
				if (IsObsoleteConfigSection(key2.Section, obsoleteSections) || IsObsoleteThemeConfig(key2))
				{
					list.Add(key2);
				}
			}
			for (int j = 0; j < list.Count; j++)
			{
				dictionary.Remove(list[j]);
			}
		}

		private static bool IsObsoleteThemeConfig(ConfigDefinition definition)
		{
			if (!string.Equals(definition.Section, "Appearance", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			string a = definition.Key ?? string.Empty;
			if (!string.Equals(a, "Theme", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "ThemeOrder", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "SelectedTheme", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "ThemeIndex", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "AllowThemeSwitching", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "ThemeHotkey", StringComparison.OrdinalIgnoreCase) && !string.Equals(a, "PreviousTheme", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(a, "NextTheme", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool IsObsoleteConfigSection(string section, string[] obsoleteSections)
		{
			for (int i = 0; i < obsoleteSections.Length; i++)
			{
				if (string.Equals(section, obsoleteSections[i], StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private void ApplyCanonicalLayoutDefaults()
		{
			_finalLeftOffsetX.Value = 0;
			_finalLeftOffsetY.Value = 0;
			_finalRoadmapOffsetX.Value = 0;
			_finalRoadmapOffsetY.Value = 0;
			_finalSagaOffsetX.Value = 0;
			_finalSagaOffsetY.Value = 0;
			_finalHubOffsetX.Value = 0;
			_finalHubOffsetY.Value = 0;
			_finalBottomBarOffsetX.Value = 0;
			_finalBottomBarOffsetY.Value = 0;
			_rightX.Value = 20;
			_rightY.Value = 70;
			_otherX.Value = 20;
			_otherY.Value = -20;
			_newsX.Value = -20;
			_newsY.Value = 70;
			_sagaX.Value = -20;
			_sagaY.Value = -20;
			_miniX[0].Value = 20;
			_miniY[0].Value = 5;
			_miniX[1].Value = 20;
			_miniY[1].Value = -98;
			_miniX[2].Value = -20;
			_miniY[2].Value = -98;
		}

		private static Rect CreateAnchoredPanelRect(ConfigEntry<int> xEntry, ConfigEntry<int> yEntry, ConfigEntry<int> widthEntry, ConfigEntry<int> heightEntry, bool rightAnchored, bool bottomAnchored, float logicalWidth, float logicalHeight)
		{
			//IL_0046: 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)
			float num = widthEntry.Value;
			float num2 = heightEntry.Value;
			float num3 = (rightAnchored ? (logicalWidth - num + (float)xEntry.Value) : ((float)xEntry.Value));
			float num4 = (bottomAnchored ? (logicalHeight - num2 + (float)yEntry.Value) : ((float)yEntry.Value));
			return ClampPanelToScreen(new Rect(num3, num4, num, num2), logicalWidth, logicalHeight);
		}

		private static Rect ClampPanelToScreen(Rect panel, float logicalWidth, float logicalHeight)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(160f, Mathf.Max(1f, ((Rect)(ref panel)).width));
			float num2 = Mathf.Min(38f, Mathf.Max(1f, ((Rect)(ref panel)).height));
			((Rect)(ref panel)).x = Mathf.Clamp(((Rect)(ref panel)).x, 0f - (((Rect)(ref panel)).width - num), Mathf.Max(0f, logicalWidth - num));
			((Rect)(ref panel)).y = Mathf.Clamp(((Rect)(ref panel)).y, 0f, Mathf.Max(0f, logicalHeight - num2));
			return panel;
		}

		private bool DrawPanelCloseButton(Rect panel, float topInset, float rightInset, float size)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return GUI.Button(new Rect(((Rect)(ref panel)).xMax - rightInset - size, ((Rect)(ref panel)).y + topInset, size, size), "×", _closeButtonStyle ?? _buttonStyle);
		}

		private void HandlePanelDrag(string id, ref Rect panel, ConfigEntry<int> xEntry, ConfigEntry<int> yEntry, bool rightAnchored, float logicalWidth, float logicalHeight, bool bottomAnchored = false)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Invalid comparison between Unknown and I4
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Invalid comparison between Unknown and I4
			if (IsolationI2StaticRuntime || _enablePanelDragging == null || !_enablePanelDragging.Value || xEntry == null || yEntry == null)
			{
				return;
			}
			Event current = Event.current;
			bool flag = current.control || Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
			if ((int)current.type == 0 && current.button == 0 && flag && ((Rect)(ref panel)).Contains(current.mousePosition))
			{
				_dragPanelId = id;
				_dragOffset = current.mousePosition - new Vector2(((Rect)(ref panel)).x, ((Rect)(ref panel)).y);
				current.Use();
			}
			if (_dragPanelId == id && (int)current.type == 3 && flag)
			{
				Vector2 val = current.mousePosition - _dragOffset;
				((Rect)(ref panel)).x = Mathf.Clamp(val.x, 0f, Mathf.Max(0f, logicalWidth - ((Rect)(ref panel)).width));
				((Rect)(ref panel)).y = Mathf.Clamp(val.y, 0f, Mathf.Max(0f, logicalHeight - ((Rect)(ref panel)).height));
				xEntry.Value = (rightAnchored ? Mathf.RoundToInt(((Rect)(ref panel)).x - (logicalWidth - ((Rect)(ref panel)).width)) : Mathf.RoundToInt(((Rect)(ref panel)).x));
				yEntry.Value = (bottomAnchored ? Mathf.RoundToInt(((Rect)(ref panel)).y - (logicalHeight - ((Rect)(ref panel)).height)) : Mathf.RoundToInt(((Rect)(ref panel)).y));
				current.Use();
			}
			if (_dragPanelId == id && ((int)current.type == 1 || !flag))
			{
				Plugin.Instance.RuntimeConfig.Save();
				_dragPanelId = null;
				if ((int)current.type == 1)
				{
					current.Use();
				}
			}
		}

		private void DrawTextureSafe(Rect rect, Texture texture, string textureName, ScaleMode scaleMode = (ScaleMode)0, bool alphaBlend = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)texture == (Object)null)
			{
				LogMissingDrawTextureOnce(textureName);
			}
			else
			{
				GUI.DrawTexture(rect, texture, scaleMode, alphaBlend);
			}
		}

		private void LogMissingDrawTextureOnce(string textureName)
		{
			string text = (string.IsNullOrEmpty(textureName) ? "unknown texture" : textureName);
			if (_missingDrawTextureLog.Add(text))
			{
				Plugin.Log.LogWarning("[FehuLanding] Missing GUI texture: " + text);
			}
		}

		private unsafe void DrawSocial(Rect panel, SocialPanelSettings settings)
		{
			//IL_0007: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Invalid comparison between Unknown and I4
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			LoadSocialIconsOnce();
			if (DrawPanelCloseButton(panel, 4f, 6f, 20f))
			{
				_socialVisible = false;
				Plugin.Log.LogInfo("[TheFehu] Close panel clicked: Social");
			}
			List<SocialLink> list = ((_content != null && _content.socialLinks != null) ? _content.socialLinks : new List<SocialLink>());
			Rect val = default(Rect);
			for (int i = 0; i < list.Count && i < 9; i++)
			{
				SocialLink socialLink = list[i];
				float num = Mathf.Max(2f, (float)settings.IconSpacing);
				float num2 = Mathf.Clamp(settings.IconSize, 48, 72);
				num2 = Mathf.Min(num2, (((Rect)(ref panel)).width - num * 8f - 24f) / 9f);
				float num3 = num2 * 9f + num * 8f;
				((Rect)(ref val))..ctor(((Rect)(ref panel)).x + (((Rect)(ref panel)).width - num3) * 0.5f + (float)i * (num2 + num), ((Rect)(ref panel)).y + (((Rect)(ref panel)).height - num2) * 0.5f, num2, num2);
				_socialIcons.TryGetValue(socialLink.Icon, out var value);
				if ((Object)value != (Object)null)
				{
					GUI.DrawTexture(val, (Texture)value, (ScaleMode)2, true);
					string key = "visible:" + socialLink.Icon;
					string[] array = new string[6] { "[TheFehu] Social icon rendered: ", socialLink.Icon, "\n[TheFehu] Social icon position: ", null, null, null };
					Rect val2 = val;
					array[3] = ((object)(*(Rect*)(&val2))/*cast due to .constrained prefix*/).ToString();
					array[4] = "\n[TheFehu] Social icon visible: ";
					array[5] = socialLink.Icon;
					LogSocialIcon(key, string.Concat(array));
				}
				if (!string.IsNullOrEmpty(socialLink.Url) && (int)Event.current.type == 1 && Event.current.button == 0 && ((Rect)(ref val)).Contains(Event.current.mousePosition))
				{
					Application.OpenURL(socialLink.Url);
					Event.current.Use();
				}
			}
		}

		private void LoadSocialIconsOnce()
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			if (_socialIconsLoaded)
			{
				return;
			}
			_socialIconsLoaded = true;
			string path = Path.Combine(Plugin.RuntimeDataPath, "Assets", "Social");
			List<string> obj = ((_content != null && _content.socialLinks != null) ? (from link in _content.socialLinks
				where !string.IsNullOrWhiteSpace(link.Icon)
				select link.Icon.Trim()).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList() : new List<string>());
			int num = 0;
			foreach (string item in obj)
			{
				string text = Path.Combine(path, item);
				LogSocialIcon("exists:" + item, "[TheFehu] Social icon file exists: " + item + " " + File.Exists(text).ToString().ToLowerInvariant());
				try
				{
					Texture2D val = LoadIcon(text);
					if ((Object)val != (Object)null)
					{
						_socialIcons[item] = val;
						num++;
						LogSocialIcon("loaded:" + text, "[TheFehu] Social icon loaded: " + item);
					}
					else
					{
						LogSocialIcon("failed:" + item, "[TheFehu] Social icon failed: " + item);
					}
				}
				catch (Exception ex)
				{
					LogSocialIcon("failed:" + item, "[TheFehu] Social icon failed: " + item + " " + ex);
				}
			}
			Plugin.Log.LogInfo("[TheFehu] Social icon count discovered: " + num);
		}

		private void LogSocialIcon(string key, string message)
		{
			if (_socialIconLog.Add(key))
			{
				Plugin.Log.LogInfo(message);
			}
		}

		private void InitializeShortcutLegendCaches()
		{
			_leftShortcutEnabled = new ConfigEntry<bool>[4] { _legendF1Enabled, _legendF3Enabled, _legendF4Enabled, _legendF6Enabled };
			_leftShortcutLabels = new ConfigEntry<string>[4] { _legendF1Label, _legendF3Label, _legendF4Label, _legendF6Label };
			_rightShortcutEnabled = new ConfigEntry<bool>[4] { _legendF7Enabled, _legendF8Enabled, _legendF9Enabled, _legendF10Enabled };
			_rightShortcutLabels = new ConfigEntry<string>[4] { _legendF7Label, _legendF8Label, _legendF9Label, _legendF10Label };
		}

		private Texture2D LoadIcon(string path)
		{
			//IL_0033: 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_0044: Expected O, but got Unknown
			//IL_005b: Expected O, but got Unknown
			if (CrashIsolationDiagnosticBuild && !Iso(_isoIconsTexturesSprites))
			{
				LogIsolationWarningOnce("IconsTexturesSpritesBypass", "[Isolation] Production icon/texture load bypassed because IsolationEnableIconsTexturesSprites=false");
				return null;
			}
			if (!File.Exists(path))
			{
				return null;
			}
			try
			{
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, File.ReadAllBytes(path));
				if (CrashIsolationDiagnosticBuild)
				{
					_isolationTexturesCreated++;
				}
				return val;
			}
			catch
			{
				return null;
			}
		}

		private void DrawMiniPanels(float logicalWidth, float logicalHeight)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			if (_miniEnabled == null)
			{
				return;
			}
			Rect val = default(Rect);
			for (int i = 0; i < 3; i++)
			{
				if (_miniEnabled[i].Value && _miniVisible[i] && (_bottomLegendEnabled == null || !_bottomLegendEnabled.Value || i <= 0))
				{
					MiniPanelSettings miniPanelSettings = new MiniPanelSettings
					{
						Enabled = true,
						X = _miniX[i].Value,
						Y = _miniY[i].Value,
						Width = _miniWidth[i].Value,
						Height = _miniHeight[i].Value,
						Text = _miniText[i].Value,
						Icons = _miniIcons[i].Value,
						Url = _miniUrl[i].Value
					};
					bool flag = miniPanelSettings.X < 0;
					bool flag2 = _useAnchoredDefaultLayout && i > 0;
					float num = (flag2 ? (logicalHeight - (float)miniPanelSettings.Height + (float)miniPanelSettings.Y) : ((float)miniPanelSettings.Y));
					val = ClampPanelToScreen(new Rect(flag ? (logicalWidth - (float)miniPanelSettings.Width + (float)miniPanelSettings.X) : ((float)min