Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of FehuLanding v420.0.1
FehuLanding.dll
Decompiled a day agousing 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; } } }