Decompiled source of FehuLanding v420.0.1

FehuLanding.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.10.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.10.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
{
	[BepInPlugin("com.forteca.thefehu", "FehuLanding", "1.0.10")]
	[BepInProcess("valheim.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.forteca.thefehu";

		public const string PluginName = "FehuLanding";

		public const string PluginVersion = "1.0.10";

		internal static ManualLogSource Log;

		private FehuMenu _menu;

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[FehuLanding] DLL LOADED VERSION 1.0.10");
			try
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[TheFehu] Startup begin");
				Instance = this;
				Log = ((BaseUnityPlugin)this).Logger;
				GameObject val = new GameObject("FehuLanding Main Menu");
				Object.DontDestroyOnLoad((Object)(object)val);
				_menu = val.AddComponent<FehuMenu>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[TheFehu] Startup complete");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[TheFehu] Startup failed: " + ex));
			}
		}
	}
	public sealed class FehuMenu : MonoBehaviour
	{
		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<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<string> _newsTitle;

		private ConfigEntry<string> _sagaTitle;

		private ConfigEntry<string> _realmsTitle;

		private ConfigEntry<string> _otherRealmsTitle;

		private ConfigEntry<float> _uiScale;

		private ConfigEntry<int> _socialIconSize;

		private ConfigEntry<int> _socialIconSpacing;

		private FehuContent _content;

		private string _contentPath;

		private bool _hiddenForSession;

		private bool _topLeftVisible = true;

		private bool _bottomLeftVisible = true;

		private bool _topRightVisible = true;

		private bool _bottomRightVisible = true;

		private bool _socialVisible = true;

		private Vector2 _newsScroll;

		private Vector2 _sagaScroll;

		private GUIStyle _titleStyle;

		private GUIStyle _bodyStyle;

		private GUIStyle _serverStyle;

		private GUIStyle _buttonStyle;

		private Texture2D _parchment;

		private Texture2D _ink;

		private Texture2D _gold;

		private Texture2D _fade;

		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 bool _socialIconsLoaded;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Expected O, but got Unknown
			ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config;
			config.Remove(new ConfigDefinition("Fehu Social", "Title"));
			config.Save();
			_enabled = config.Bind<bool>("General", "EnableTheFehu", true, "Enable the TheFehu main-menu boards.");
			_showOnMainMenu = config.Bind<bool>("General", "ShowOnMainMenu", true, "Show the boards whenever the main menu opens.");
			_hideChangelog = config.Bind<bool>("Vanilla Menu", "HideChangelog", false, (ConfigDescription)null);
			_hideMerchStore = config.Bind<bool>("Vanilla Menu", "HideMerchStore", false, (ConfigDescription)null);
			_hideVersionText = config.Bind<bool>("Vanilla Menu", "HideVersionText", false, (ConfigDescription)null);
			_hideModdedWarningText = config.Bind<bool>("Vanilla Menu", "HideModdedWarningText", true, (ConfigDescription)null);
			if (!_hideModdedWarningText.Value)
			{
				_hideModdedWarningText.Value = true;
				config.Save();
			}
			_hideShowLogButton = config.Bind<bool>("Vanilla Menu", "HideShowLogButton", false, (ConfigDescription)null);
			_newsEnabled = config.Bind<bool>("News Board", "Enabled", true, (ConfigDescription)null);
			_newsX = config.Bind<int>("News Board", "X", 20, (ConfigDescription)null);
			_newsY = config.Bind<int>("News Board", "Y", 70, (ConfigDescription)null);
			_newsWidth = config.Bind<int>("News Board", "Width", 460, (ConfigDescription)null);
			_newsHeight = config.Bind<int>("News Board", "Height", 475, (ConfigDescription)null);
			_newsTitle = config.Bind<string>("News Board", "Title", "Announcements", (ConfigDescription)null);
			_sagaEnabled = config.Bind<bool>("Skald Saga Board", "Enabled", true, (ConfigDescription)null);
			_sagaX = config.Bind<int>("Skald Saga Board", "X", 20, (ConfigDescription)null);
			_sagaY = config.Bind<int>("Skald Saga Board", "Y", 550, (ConfigDescription)null);
			_sagaWidth = config.Bind<int>("Skald Saga Board", "Width", 460, (ConfigDescription)null);
			_sagaHeight = config.Bind<int>("Skald Saga Board", "Height", 500, (ConfigDescription)null);
			_sagaTitle = config.Bind<string>("Skald Saga Board", "Title", "Saga Chronicles", (ConfigDescription)null);
			_realmsEnabled = config.Bind<bool>("Realms Board", "Enabled", true, (ConfigDescription)null);
			_rightX = config.Bind<int>("Realms Board", "X", -20, (ConfigDescription)null);
			_rightY = config.Bind<int>("Realms Board", "Y", 70, (ConfigDescription)null);
			_rightWidth = config.Bind<int>("Realms Board", "Width", 460, (ConfigDescription)null);
			_rightHeight = config.Bind<int>("Realms Board", "Height", 475, (ConfigDescription)null);
			_realmsTitle = config.Bind<string>("Realms Board", "Title", "Fehu Realms", (ConfigDescription)null);
			_otherRealmsEnabled = config.Bind<bool>("Other Realms Board", "Enabled", true, (ConfigDescription)null);
			_otherX = config.Bind<int>("Other Realms Board", "X", -20, (ConfigDescription)null);
			_otherY = config.Bind<int>("Other Realms Board", "Y", 550, (ConfigDescription)null);
			_otherWidth = config.Bind<int>("Other Realms Board", "Width", 460, (ConfigDescription)null);
			_otherHeight = config.Bind<int>("Other Realms Board", "Height", 500, (ConfigDescription)null);
			_otherRealmsTitle = config.Bind<string>("Other Realms Board", "Title", "Other Realms", (ConfigDescription)null);
			_socialEnabled = config.Bind<bool>("SocialPanel", "Enabled", true, (ConfigDescription)null);
			_socialX = config.Bind<int>("SocialPanel", "X", -20, (ConfigDescription)null);
			_socialY = config.Bind<int>("SocialPanel", "Y", 10, (ConfigDescription)null);
			_socialWidth = config.Bind<int>("SocialPanel", "Width", 620, (ConfigDescription)null);
			_socialHeight = config.Bind<int>("SocialPanel", "Height", 80, (ConfigDescription)null);
			_socialIconSize = config.Bind<int>("SocialPanel", "SocialIconSize", 42, (ConfigDescription)null);
			_socialIconSpacing = config.Bind<int>("SocialPanel", "SocialIconSpacing", 8, (ConfigDescription)null);
			Plugin.Log.LogInfo((object)"[TheFehu] SocialPanel config applied X/Y/W/H/IconSize/IconSpacing");
			_uiScale = config.Bind<float>("General", "UIScale", 1f, new ConfigDescription("Additional UI scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
			_contentPath = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "FehuLanding.json");
			LoadContent();
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (IsMainMenu())
			{
				_hiddenForSession = false;
				_topLeftVisible = (_bottomLeftVisible = (_topRightVisible = (_bottomRightVisible = (_socialVisible = true))));
				((MonoBehaviour)this).StartCoroutine(HideVanillaMenuAfterLoad());
			}
		}

		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 (Input.GetKeyDown((KeyCode)288) && IsMainMenu())
			{
				_hiddenForSession = !_hiddenForSession;
				_topLeftVisible = (_bottomLeftVisible = (_topRightVisible = (_bottomRightVisible = (_socialVisible = !_hiddenForSession))));
				Plugin.Log.LogInfo((object)"[TheFehu] F7 toggle all panels");
			}
		}

		private void OnGUI()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			if (_enabled.Value && _showOnMainMenu.Value && !_hiddenForSession && IsMainMenu())
			{
				if (_content == null)
				{
					LoadContent();
				}
				if (_titleStyle == null)
				{
					BuildTheme();
					HideVanillaMenu();
				}
				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;
				if (_newsEnabled.Value && _topLeftVisible)
				{
					DrawStoryBoard("TopLeft", new Rect((float)_newsX.Value, (float)_newsY.Value, (float)_newsWidth.Value, (float)_newsHeight.Value), string.IsNullOrEmpty(_newsTitle.Value) ? _content.newsTitle : _newsTitle.Value, _content.newsText, ref _newsScroll, ref _topLeftVisible);
				}
				if (_sagaEnabled.Value && _bottomLeftVisible)
				{
					DrawStoryBoard("BottomLeft", new Rect((float)_sagaX.Value, (float)_sagaY.Value, (float)_sagaWidth.Value, (float)_sagaHeight.Value), string.IsNullOrEmpty(_sagaTitle.Value) ? _content.sagaTitle : _sagaTitle.Value, _content.sagaText, ref _sagaScroll, ref _bottomLeftVisible);
				}
				if (_realmsEnabled.Value && _topRightVisible)
				{
					DrawRealmsBoard("TopRight", new Rect(num2 - (float)_rightWidth.Value + (float)_rightX.Value, (float)_rightY.Value, (float)_rightWidth.Value, (float)_rightHeight.Value), string.IsNullOrEmpty(_realmsTitle.Value) ? _content.realmsTitle : _realmsTitle.Value, ServersFrom(0, 5), ref _topRightVisible);
				}
				if (_otherRealmsEnabled.Value && _bottomRightVisible)
				{
					DrawRealmsBoard("BottomRight", new Rect(num2 - (float)_otherWidth.Value + (float)_otherX.Value, (float)_otherY.Value, (float)_otherWidth.Value, (float)_otherHeight.Value), _otherRealmsTitle.Value, ServersFrom(5, int.MaxValue), ref _bottomRightVisible);
				}
				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)
				{
					DrawSocial(new Rect(num2 - (float)socialPanelSettings.Width + (float)socialPanelSettings.X, (float)socialPanelSettings.Y, (float)socialPanelSettings.Width, (float)socialPanelSettings.Height), socialPanelSettings);
				}
				GUI.matrix = matrix;
				GUI.depth = depth;
			}
		}

		private unsafe void DrawSocial(Rect panel, SocialPanelSettings settings)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			LoadSocialIconsOnce();
			GUI.DrawTexture(panel, (Texture)(object)_parchment, (ScaleMode)0);
			if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 28f, ((Rect)(ref panel)).y + 4f, 20f, 20f), "x", _buttonStyle))
			{
				_socialVisible = false;
				Plugin.Log.LogInfo((object)"[TheFehu] Close panel clicked: Social");
			}
			List<SocialLink> list = DefaultSocialLinks();
			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, 32, 48);
				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);
				GUI.Box(val, (GUIContent)((!((Object)(object)value == (Object)null)) ? ((object)GUIContent.none) : ((object)new GUIContent(socialLink.Title.Substring(0, 1)))), _buttonStyle);
				if ((Object)(object)value != (Object)null)
				{
					GUI.DrawTexture(val, (Texture)(object)value, (ScaleMode)2, true);
					string key = "visible:" + socialLink.Icon;
					string[] obj = new string[6] { "[TheFehu] Social icon rendered: ", socialLink.Icon, "\n[TheFehu] Social icon position: ", null, null, null };
					Rect val2 = val;
					obj[3] = ((object)(*(Rect*)(&val2))/*cast due to .constrained prefix*/).ToString();
					obj[4] = "\n[TheFehu] Social icon visible: ";
					obj[5] = socialLink.Icon;
					LogSocialIcon(key, string.Concat(obj));
				}
				if (!string.IsNullOrEmpty(socialLink.Url) && GUI.Button(val, GUIContent.none, GUIStyle.none))
				{
					Application.OpenURL(socialLink.Url);
				}
			}
		}

		private void LoadSocialIconsOnce()
		{
			if (_socialIconsLoaded)
			{
				return;
			}
			_socialIconsLoaded = true;
			string[] obj = new string[9] { "discord.png", "facebook.png", "instagram.png", "pinterest.png", "soundcloud.png", "steam.png", "tiktok.png", "twitch.png", "youtube.png" };
			string path = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "Assets", "social");
			int num = 0;
			string[] array = obj;
			foreach (string text in array)
			{
				string text2 = Path.Combine(path, text);
				LogSocialIcon("exists:" + text, "[TheFehu] Social icon file exists: " + text + " " + File.Exists(text2).ToString().ToLowerInvariant());
				try
				{
					Texture2D val = LoadIcon(text2);
					if ((Object)(object)val != (Object)null)
					{
						_socialIcons[text] = val;
						num++;
						LogSocialIcon("loaded:" + text2, "[TheFehu] Social icon loaded: " + text);
					}
					else
					{
						LogSocialIcon("failed:" + text, "[TheFehu] Social icon failed: " + text);
					}
				}
				catch (Exception ex)
				{
					LogSocialIcon("failed:" + text, "[TheFehu] Social icon failed: " + text + " " + ex);
				}
			}
			Plugin.Log.LogInfo((object)("[TheFehu] Social icon count discovered: " + num));
		}

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

		private static Texture2D LoadIcon(string path)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0020: Expected O, but got Unknown
			if (!File.Exists(path))
			{
				return null;
			}
			try
			{
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, File.ReadAllBytes(path));
				return val;
			}
			catch
			{
				return null;
			}
		}

		private static string SocialUrl(string name)
		{
			return name switch
			{
				"discord.png" => "https://discord.gg/", 
				"facebook.png" => "https://facebook.com/", 
				"instagram.png" => "https://instagram.com/", 
				"pinterest.png" => "https://pinterest.com/", 
				"soundcloud.png" => "https://soundcloud.com/", 
				"steam.png" => "https://store.steampowered.com/", 
				"tiktok.png" => "https://tiktok.com/", 
				"twitch.png" => "https://twitch.tv/", 
				"youtube.png" => "https://youtube.com/", 
				_ => string.Empty, 
			};
		}

		private void DrawStoryBoard(string id, Rect panel, string title, string text, ref Vector2 scroll, ref bool visible)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(panel, (Texture)(object)_parchment, (ScaleMode)0);
			GUI.Label(new Rect(((Rect)(ref panel)).x + 35f, ((Rect)(ref panel)).y + 23f, ((Rect)(ref panel)).width - 70f, 38f), "ᚱ  " + title + "  ᚱ", _titleStyle);
			GUI.DrawTexture(new Rect(((Rect)(ref panel)).x + 42f, ((Rect)(ref panel)).y + 68f, ((Rect)(ref panel)).width - 84f, 2f), (Texture)(object)_gold);
			if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 47f, ((Rect)(ref panel)).y + 22f, 25f, 25f), "×", _buttonStyle))
			{
				visible = false;
				Plugin.Log.LogInfo((object)("[TheFehu] Close panel clicked: " + id));
			}
			DrawNews(panel, text, ref scroll);
		}

		private void DrawRealmsBoard(string id, Rect panel, string title, List<FehuServer> servers, ref bool visible)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(panel, (Texture)(object)_parchment, (ScaleMode)0);
			GUI.Label(new Rect(((Rect)(ref panel)).x + 35f, ((Rect)(ref panel)).y + 23f, ((Rect)(ref panel)).width - 70f, 38f), "ᚱ  " + title + "  ᚱ", _titleStyle);
			GUI.DrawTexture(new Rect(((Rect)(ref panel)).x + 42f, ((Rect)(ref panel)).y + 68f, ((Rect)(ref panel)).width - 84f, 2f), (Texture)(object)_gold);
			if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 47f, ((Rect)(ref panel)).y + 22f, 25f, 25f), "×", _buttonStyle))
			{
				visible = false;
				Plugin.Log.LogInfo((object)("[TheFehu] Close panel clicked: " + id));
			}
			DrawServers(panel, servers);
		}

		private void DrawNews(Rect panel, string text, ref Vector2 scroll)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref panel)).x + 42f, ((Rect)(ref panel)).y + 88f, ((Rect)(ref panel)).width - 84f, ((Rect)(ref panel)).height - 122f);
			string[] lines = (string.IsNullOrWhiteSpace(text) ? "# No tale has been written yet." : text).Split(new char[1] { '\n' });
			float num = NewsHeight(lines, ((Rect)(ref val)).width - 8f);
			if (((Rect)(ref val)).Contains(Event.current.mousePosition) && (int)Event.current.type == 6)
			{
				scroll.y = Mathf.Clamp(scroll.y + Event.current.delta.y * 26f, 0f, Mathf.Max(0f, num - ((Rect)(ref val)).height));
				Event.current.Use();
			}
			GUI.BeginGroup(val);
			DrawNewsLines(lines, 0f - scroll.y, ((Rect)(ref val)).width - 8f);
			GUI.EndGroup();
			for (int i = 0; i < 6; i++)
			{
				float num2 = 0.6f - (float)i * 0.09f;
				GUI.color = new Color(0.86f, 0.65f, 0.31f, num2);
				GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + (float)i * 4f, ((Rect)(ref val)).width, 5f), (Texture)(object)_fade);
				GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).yMax - 5f - (float)i * 4f, ((Rect)(ref val)).width, 5f), (Texture)(object)_fade);
			}
			GUI.color = Color.white;
		}

		private float NewsHeight(string[] lines, float width)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			float num = 10f;
			foreach (string text in lines)
			{
				num += ((text.Trim() == "---") ? 20f : (text.StartsWith("# ") ? 34f : (Mathf.Max(22f, _bodyStyle.CalcHeight(new GUIContent(text), width)) + 7f)));
			}
			return num;
		}

		private void DrawNewsLines(string[] lines, float y, float width)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < lines.Length; i++)
			{
				string text = lines[i].TrimEnd(new char[1] { '\r' });
				if (text.Trim() == "---")
				{
					GUI.DrawTexture(new Rect(8f, y + 9f, width - 16f, 1f), (Texture)(object)_gold);
					y += 20f;
				}
				else if (text.StartsWith("# "))
				{
					GUI.Label(new Rect(8f, y, width - 16f, 28f), text.Substring(2), _serverStyle);
					y += 34f;
				}
				else
				{
					float num = Mathf.Max(22f, _bodyStyle.CalcHeight(new GUIContent(text), width));
					GUI.Label(new Rect(8f, y, width - 16f, num), text, _bodyStyle);
					y += num + 7f;
				}
			}
		}

		private List<FehuServer> ServersFrom(int start, int count)
		{
			List<FehuServer> list = new List<FehuServer>();
			List<FehuServer> list2 = _content.servers ?? new List<FehuServer>();
			for (int i = start; i < list2.Count; i++)
			{
				if (list.Count >= count)
				{
					break;
				}
				list.Add(list2[i]);
			}
			return list;
		}

		private void DrawServers(Rect panel, List<FehuServer> servers)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Rect)(ref panel)).y + 78f;
			float num2 = ((Rect)(ref panel)).width - 56f;
			foreach (FehuServer server in servers)
			{
				if (num + 62f > ((Rect)(ref panel)).yMax - 62f)
				{
					break;
				}
				GUI.Label(new Rect(((Rect)(ref panel)).x + 36f, num, num2, 24f), "⚔ " + (server.name ?? "Unnamed server"), _serverStyle);
				GUI.Label(new Rect(((Rect)(ref panel)).x + 40f, num + 26f, 250f, 20f), (server.players ?? "—") + " Warriors Online", _bodyStyle);
				if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 175f, num + 19f, 65f, 29f), "Join", _buttonStyle))
				{
					OpenJoin(server);
				}
				if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 104f, num + 19f, 75f, 29f), "Copy IP", _buttonStyle))
				{
					CopyAddress(server);
				}
				GUI.DrawTexture(new Rect(((Rect)(ref panel)).x + 36f, num + 47f, num2 - 14f, 1f), (Texture)(object)_gold);
				num += 52f;
			}
			LogSocialIcon("realm-links-removed", "[TheFehu] Removed old realm social buttons");
		}

		private void DrawLinkButton(Rect rect, string label, string url)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (GUI.Button(rect, label, _buttonStyle) && Uri.IsWellFormedUriString(url, UriKind.Absolute))
			{
				Application.OpenURL(url);
			}
		}

		private static List<SocialLink> DefaultSocialLinks()
		{
			string[] obj = new string[9] { "discord", "facebook", "instagram", "pinterest", "soundcloud", "steam", "tiktok", "twitch", "youtube" };
			List<SocialLink> list = new List<SocialLink>();
			string[] array = obj;
			foreach (string text in array)
			{
				list.Add(new SocialLink
				{
					Title = text,
					Icon = text + ".png",
					Url = ""
				});
			}
			return list;
		}

		private static void OpenJoin(FehuServer server)
		{
			if (server != null && !string.IsNullOrWhiteSpace(server.address) && server.port >= 1)
			{
				Application.OpenURL("steam://connect/" + server.address.Trim() + ":" + server.port);
			}
		}

		private static void CopyAddress(FehuServer server)
		{
			if (server != null && !string.IsNullOrWhiteSpace(server.address) && server.port >= 1)
			{
				GUIUtility.systemCopyBuffer = server.address.Trim() + ":" + server.port;
			}
		}

		private bool IsMainMenu()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!string.Equals(name, "start", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(name, "main", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private void HideVanillaMenu()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsMainMenu() || !_hideModdedWarningText.Value)
			{
				return;
			}
			Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
			foreach (Transform val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (!((Scene)(ref scene)).IsValid() || IsOurObject(val))
				{
					continue;
				}
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					PropertyInfo property = ((object)val2).GetType().GetProperty("text");
					if (!(property == null) && !(property.PropertyType != typeof(string)) && property.CanRead)
					{
						string text = property.GetValue(val2, null) as string;
						if (!string.IsNullOrEmpty(text) && IsModdedWarningText(text))
						{
							HideText(val2, "Modded Warning Text");
							break;
						}
					}
				}
			}
		}

		private bool IsOurObject(Transform transform)
		{
			if (!((Object)(object)transform == (Object)null) && !((Object)(object)transform == (Object)(object)((Component)this).transform) && !((Object)(object)transform.root == (Object)(object)((Component)this).transform) && ((Object)transform.root).name.IndexOf("TheFehu", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return ((Object)transform.root).name.IndexOf("FehuLanding", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static bool IsModdedWarningText(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string text2 = Regex.Replace(text, "\\s+", " ").Trim();
			if (text2.IndexOf("You are playing a modded version of Valheim", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("this may change the original game experience", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text2.IndexOf("uninstall all mods before reporting it", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private void HideModdedWarning(Transform label)
		{
			Transform val = label;
			Transform val2 = label;
			for (int i = 0; i < 3; i++)
			{
				if (!((Object)(object)val.parent != (Object)null))
				{
					break;
				}
				val = val.parent;
				val2 = val;
				if (CountTextComponents(val) >= 1 && CountUiImages(val) == 0)
				{
					HideObject(((Component)val).gameObject, "Modded Warning Text");
					return;
				}
			}
			HideObject(((Component)val2).gameObject, "Modded Warning Text");
		}

		private static int CountTextComponents(Transform root)
		{
			int num = 0;
			Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					PropertyInfo property = ((object)val).GetType().GetProperty("text");
					if (property != null && property.PropertyType == typeof(string) && property.CanRead)
					{
						num++;
					}
				}
			}
			return num;
		}

		private static bool IsMerchObjectName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			if (name.IndexOf("Merch", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("StoreButton", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("TShirt", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("T-Shirt", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Shirt", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Mug", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return name.IndexOf("Cup", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static bool IsShowLogObjectName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			if (name.IndexOf("ShowLog", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Player.log", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return name.IndexOf("PlayerLog", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static GameObject BestButtonRoot(Transform transform)
		{
			Transform val = transform;
			Transform val2 = transform;
			for (int i = 0; i < 3; i++)
			{
				if (!((Object)(object)val != (Object)null))
				{
					break;
				}
				val2 = val;
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val3 in components)
				{
					if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().Name.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return ((Component)val).gameObject;
					}
				}
				val = val.parent;
			}
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return ((Component)val2).gameObject;
		}

		private void LogMerchCandidates()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)"[TheFehu] Searching Merch Store UI...");
			Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
			foreach (Transform val in array)
			{
				Scene scene = ((Component)val).gameObject.scene;
				if (!((Scene)(ref scene)).IsValid() || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				Component[] components = ((Component)val).GetComponents<Component>();
				string text = string.Empty;
				List<string> list = new List<string>();
				bool flag = false;
				Component[] array2 = components;
				foreach (Component val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						Type type = ((object)val2).GetType();
						list.Add(type.Name);
						if (type.Name.IndexOf("Button", StringComparison.OrdinalIgnoreCase) >= 0 || type.Name.IndexOf("Clickable", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							flag = true;
						}
						PropertyInfo property = type.GetProperty("text");
						if (property != null && property.PropertyType == typeof(string) && property.CanRead)
						{
							text = (property.GetValue(val2, null) as string) ?? text;
						}
					}
				}
				string text2 = (((Object)val).name + " " + text).ToUpperInvariant();
				bool num = text2.Contains("MERCH") || text2.Contains("STORE") || text2.Contains("SHOP") || text2.Contains("TSHIRT") || text2.Contains("SHIRT") || text2.Contains("MUG") || text2.Contains("DONATE") || text2.Contains("SUPPORT");
				bool flag2 = list.Exists((string t) => t.IndexOf("Image", StringComparison.OrdinalIgnoreCase) >= 0);
				if (num || (flag && flag2))
				{
					string text3 = (((Object)(object)val.root != (Object)null) ? ((Object)val.root).name : ((Object)val).name);
					string text4 = (((Object)(object)val.parent != (Object)null) ? ((Object)val.parent).name : "<none>");
					Plugin.Log.LogInfo((object)("[TheFehu] Merch Candidate Found\nPath: " + ObjectPath(val) + "\nRoot: " + text3 + "\nParent: " + text4 + "\nName: " + ((Object)val).name + "\nComponents: " + string.Join(", ", list) + "\nText: " + text));
				}
			}
		}

		private void HideObject(GameObject target, string label)
		{
			if (!((Object)(object)target == (Object)null) && !((Object)(object)target == (Object)(object)((Component)this).gameObject))
			{
				string path = ObjectPath(target.transform);
				target.SetActive(false);
				LogHidden(label, path);
			}
		}

		private void HideText(Component component, string label)
		{
			string path = ObjectPath(component.transform);
			component.gameObject.SetActive(false);
			LogHidden(label, path);
		}

		private void HideMerchAdvertisement(Transform label)
		{
			Transform val = label;
			Transform val2 = label;
			for (int i = 0; i < 5; i++)
			{
				if (!((Object)(object)val.parent != (Object)null))
				{
					break;
				}
				val = val.parent;
				val2 = val;
				if (CountUiImages(val) >= 2 || IsMerchObjectName(((Object)val).name))
				{
					HideObject(((Component)val).gameObject, "Merch Store");
					return;
				}
			}
			HideObject(((Component)val2).gameObject, "Merch Store");
		}

		private static int CountUiImages(Transform root)
		{
			int num = 0;
			Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name == "Image" || name == "RawImage")
					{
						num++;
					}
				}
			}
			return num;
		}

		private void HideChangelog(Transform label)
		{
			Transform val = (((Object)(object)label.parent != (Object)null) ? label.parent : label);
			HideObject(((Component)val).gameObject, "Changelog");
		}

		private void LogHidden(string label, string path)
		{
			if (_hiddenLog.Add(label + path))
			{
				Plugin.Log.LogInfo((object)("[TheFehu] Hidden " + label + ": " + path));
			}
		}

		private static string ObjectPath(Transform value)
		{
			string text = ((Object)value).name;
			while ((Object)(object)value.parent != (Object)null)
			{
				value = value.parent;
				text = ((Object)value).name + "/" + text;
			}
			return text;
		}

		private void LoadContent()
		{
			FehuContent fehuContent = FehuContent.CreateDefault();
			try
			{
				if (!File.Exists(_contentPath))
				{
					File.WriteAllText(_contentPath, "{\n  \"rightTitle\": \"FEHU REALMS\",\n  \"leftTitle\": \"FEHU NEWS\",\n  \"leftText\": \"# 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\",\n  \"servers\": [\n    { \"name\": \"Fehu 10th World\", \"address\": \"play.forteca.net\", \"port\": 2456, \"status\": \"Online\", \"players\": \"32/64\" },\n    { \"name\": \"Dominion\", \"address\": \"dominion.forteca.net\", \"port\": 2456, \"status\": \"Online\", \"players\": \"7/64\" }\n  ],\n  \"links\": { \"discord\": \"https://discord.gg/YOURCODE\", \"website\": \"https://forteca.net\", \"support\": \"https://forteca.net/support\" }\n}");
				}
				_content = FehuJson.Parse(File.ReadAllText(_contentPath)) ?? fehuContent;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not load FehuLanding.json; using defaults. " + ex.Message));
				_content = fehuContent;
			}
		}

		private void BuildTheme()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			_parchment = LoadParchment();
			_ink = Solid(new Color(0.1f, 0.055f, 0.025f, 0.85f));
			_gold = Solid(new Color(0.48f, 0.19f, 0.035f, 0.75f));
			_fade = Solid(Color.white);
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 27,
				fontStyle = (FontStyle)1
			};
			val.normal.textColor = new Color(0.55f, 0.18f, 0.025f);
			_titleStyle = val;
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				wordWrap = true,
				fontSize = 16,
				richText = true
			};
			val2.normal.textColor = new Color(0.16f, 0.075f, 0.03f);
			_bodyStyle = val2;
			GUIStyle val3 = new GUIStyle(_bodyStyle)
			{
				fontSize = 19,
				fontStyle = (FontStyle)1
			};
			val3.normal.textColor = new Color(0.4f, 0.13f, 0.02f);
			_serverStyle = val3;
			GUIStyle val4 = new GUIStyle(GUI.skin.button)
			{
				fontSize = 14,
				fontStyle = (FontStyle)1
			};
			val4.normal.background = _ink;
			val4.normal.textColor = new Color(1f, 0.76f, 0.35f);
			val4.hover.background = _gold;
			val4.hover.textColor = Color.white;
			val4.active.background = _gold;
			val4.active.textColor = Color.white;
			_buttonStyle = val4;
		}

		private static Texture2D LoadParchment()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0073: Expected O, but got Unknown
			string name = Array.Find(typeof(Plugin).Assembly.GetManifestResourceNames(), (string n) => n.EndsWith("Assets.Parchment.png", StringComparison.OrdinalIgnoreCase));
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream(name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, memoryStream.ToArray());
			return val;
		}

		private static Texture2D Solid(Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private static Texture2D WoodTexture(Color light, Color dark, float alpha)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = Mathf.PerlinNoise((float)j * 0.045f, (float)i * 0.18f) * 0.45f + Mathf.PerlinNoise((float)j * 0.012f, (float)i * 0.48f) * 0.55f;
					float num2 = Mathf.Sin((float)i * 0.44f + Mathf.PerlinNoise((float)j * 0.05f, (float)i * 0.04f) * 2f) * 0.08f;
					Color val2 = Color.Lerp(dark, light, Mathf.Clamp01(num + num2));
					val2.a = alpha;
					val.SetPixel(j, i, val2);
				}
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			val.Apply();
			return val;
		}
	}
	[Serializable]
	public sealed class FehuContent
	{
		public string newsTitle;

		public string newsText;

		public string sagaTitle;

		public string sagaText;

		public string realmsTitle;

		public SocialPanelSettings socialPanel;

		public List<SocialLink> socialLinks;

		public List<FehuServer> servers;

		public FehuLinks links;

		public static FehuContent CreateDefault()
		{
			return new FehuContent
			{
				newsTitle = "FEHU NEWS",
				sagaTitle = "SKALD SAGA",
				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 = "The saga has not begun yet.",
				servers = new List<FehuServer>
				{
					new FehuServer("Fehu 10th World", "play.forteca.net", 2456, "Online", "32/64"),
					new FehuServer("Dominion", "dominion.forteca.net", 2456, "Online", "12/64"),
					new FehuServer("Conquest", "conquest.forteca.net", 2456, "Online", "7/64")
				},
				links = new FehuLinks
				{
					discord = "https://discord.gg/YOURCODE",
					website = "https://forteca.net",
					support = "https://forteca.net/support"
				}
			};
		}
	}
	[Serializable]
	public sealed class FehuServer
	{
		public string name;

		public string address;

		public string status;

		public string players;

		public int port;

		public FehuServer()
		{
		}

		public FehuServer(string name, string address, int port, string status, string players)
		{
			this.name = name;
			this.address = address;
			this.port = port;
			this.status = status;
			this.players = players;
		}
	}
	[Serializable]
	public sealed class FehuLinks
	{
		public string discord;

		public string website;

		public string support;
	}
	public sealed class SocialPanelSettings
	{
		public bool Enabled;

		public int X;

		public int Y;

		public int Width;

		public int Height;

		public int IconSize;

		public int IconSpacing;
	}
	public sealed class SocialLink
	{
		public string Title;

		public string Icon;

		public string Url;
	}
	internal static class FehuJson
	{
		internal const string DefaultText = "{\n  \"rightTitle\": \"FEHU REALMS\",\n  \"leftTitle\": \"FEHU NEWS\",\n  \"leftText\": \"# 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\",\n  \"servers\": [\n    { \"name\": \"Fehu 10th World\", \"address\": \"play.forteca.net\", \"port\": 2456, \"status\": \"Online\", \"players\": \"32/64\" },\n    { \"name\": \"Dominion\", \"address\": \"dominion.forteca.net\", \"port\": 2456, \"status\": \"Online\", \"players\": \"7/64\" }\n  ],\n  \"links\": { \"discord\": \"https://discord.gg/YOURCODE\", \"website\": \"https://forteca.net\", \"support\": \"https://forteca.net/support\" }\n}";

		internal static FehuContent Parse(string json)
		{
			if (string.IsNullOrWhiteSpace(json))
			{
				return null;
			}
			FehuContent fehuContent = FehuContent.CreateDefault();
			FehuContent fehuContent2 = new FehuContent
			{
				newsTitle = ReadString(json, "newsTitle", ReadString(json, "leftTitle", fehuContent.newsTitle)),
				newsText = ReadString(json, "newsText", ReadString(json, "leftText", fehuContent.newsText)),
				sagaTitle = ReadString(json, "sagaTitle", fehuContent.sagaTitle),
				sagaText = ReadString(json, "sagaText", fehuContent.sagaText),
				realmsTitle = ReadString(json, "realmsTitle", ReadString(json, "rightTitle", fehuContent.realmsTitle)),
				servers = new List<FehuServer>(),
				links = new FehuLinks()
			};
			fehuContent2.socialPanel = new SocialPanelSettings
			{
				Enabled = true,
				X = -20,
				Y = 35,
				Width = 620,
				Height = 80,
				IconSize = 42,
				IconSpacing = 8
			};
			string json2 = ReadSection(json, "SocialPanel", '{', '}');
			fehuContent2.socialPanel.Enabled = ReadBool(json2, "Enabled", fehuContent2.socialPanel.Enabled);
			fehuContent2.socialPanel.X = ReadInt(json2, "X", fehuContent2.socialPanel.X);
			fehuContent2.socialPanel.Y = ReadInt(json2, "Y", fehuContent2.socialPanel.Y);
			fehuContent2.socialPanel.Width = ReadInt(json2, "Width", fehuContent2.socialPanel.Width);
			fehuContent2.socialPanel.Height = ReadInt(json2, "Height", fehuContent2.socialPanel.Height);
			fehuContent2.socialPanel.IconSize = ReadInt(json2, "IconSize", fehuContent2.socialPanel.IconSize);
			fehuContent2.socialPanel.IconSpacing = ReadInt(json2, "IconSpacing", fehuContent2.socialPanel.IconSpacing);
			fehuContent2.socialLinks = new List<SocialLink>();
			foreach (Match item in Regex.Matches(ReadSection(json, "SocialLinks", '[', ']') ?? "", "\\{(?<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, "servers", '[', ']') ?? string.Empty, "\\{(?<server>[^{}]*)\\}"))
			{
				string value2 = item2.Groups["server"].Value;
				fehuContent2.servers.Add(new FehuServer(ReadString(value2, "name", "Unnamed server"), ReadString(value2, "address", string.Empty), ReadInt(value2, "port", 2456), ReadString(value2, "status", "Unknown"), ReadString(value2, "players", "—")));
			}
			if (fehuContent2.servers.Count == 0)
			{
				fehuContent2.servers = fehuContent.servers;
			}
			string json3 = ReadSection(json, "links", '{', '}');
			fehuContent2.links.discord = ReadString(json3, "discord", fehuContent.links.discord);
			fehuContent2.links.website = ReadString(json3, "website", fehuContent.links.website);
			fehuContent2.links.support = ReadString(json3, "support", fehuContent.links.support);
			return fehuContent2;
		}

		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;
		}
	}
}