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.1.17
plugins/FehuLanding.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("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 { internal sealed class ActiveServerQuery { public readonly ServerQueryWorkItem Item; public readonly string CacheKey; public readonly int Generation; public readonly HServerQuery Handle; public readonly ISteamMatchmakingPingResponse Handler; public readonly DateTime StartedUtc; public bool Cancelled; public ActiveServerQuery(ServerQueryWorkItem item, string cacheKey, int generation, HServerQuery handle, ISteamMatchmakingPingResponse handler) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Item = item; CacheKey = cacheKey; Generation = generation; Handle = handle; Handler = handler; StartedUtc = DateTime.UtcNow; } } [Serializable] public sealed class FehuContent { public string newsTitle; public string newsText; public string sagaTitle; public string sagaText; public string realmsTitle; public int ServerIconSize; public int ServerIconSpacing; public SocialPanelSettings socialPanel; public List<SocialLink> socialLinks; public List<FehuServer> servers; public FehuLinks links; public List<MiniPanelSettings> miniPanels; public static FehuContent CreateDefault() { return new FehuContent { newsTitle = "Development Roadmap", sagaTitle = "Saga Chronicles", realmsTitle = "FEHU REALMS", newsText = "# Latest News\n---\nShared Clans are now live.\n\nClan portals now use exact permissions.\n\nGames framework expanded.\n---\n# Upcoming\n---\nSkald Saga Integration\nKingdom Buildings\nNPC Guards", sagaText = "Connecting...", servers = new List<FehuServer> { new FehuServer("10th World", "play.forteca.net", 2456, string.Empty, string.Empty), new FehuServer("Adventure", "play.forteca.net", 2458, string.Empty, string.Empty), new FehuServer("Immersive", "play.forteca.net", 2460, string.Empty, string.Empty), new FehuServer("Conquest", "play.forteca.net", 2462, string.Empty, string.Empty), new FehuServer("Dominion", "play.forteca.net", 2464, string.Empty, string.Empty), new FehuServer("Builders Heaven", "play.forteca.net", 2468, string.Empty, string.Empty), new FehuServer("Balrond Realm", "play.forteca.net", 2474, string.Empty, string.Empty), new FehuServer("Aurora III", "play.forteca.net", 2470, string.Empty, string.Empty), new FehuServer("Black Ymir", "play.forteca.net", 2466, string.Empty, string.Empty), new FehuServer("Test Server", "play.forteca.net", 2472, string.Empty, string.Empty) }, links = new FehuLinks { discord = "https://discord.gg/YOURCODE", website = "https://forteca.net", support = "https://forteca.net/support" }, ServerIconSize = 28, ServerIconSpacing = 6 }; } } internal static class FehuJson { internal const string DefaultText = "{\n \"newsTitle\": \"Development Roadmap\",\n \"newsText\": \"# Latest News\\n---\\nShared Clans are now live.\",\n \"sagaTitle\": \"Saga Chronicles\",\n \"sagaText\": \"Connecting...\",\n \"realmsTitle\": \"FEHU REALMS\",\n \"servers\": [\n { \"name\": \"10th World\", \"address\": \"play.forteca.net\", \"port\": 2456, \"queryPort\": 2457, \"description\": \"The Eternal Realm\\nOne Save To Rule Them ALL\\nMarket \\u2022 Settlement\", \"icon\": \"10th.png\" },\n { \"name\": \"Adventure\", \"address\": \"play.forteca.net\", \"port\": 2458, \"queryPort\": 2459, \"description\": \"Events and expeditions\", \"icon\": \"event.png\" },\n { \"name\": \"Immersive\", \"address\": \"play.forteca.net\", \"port\": 2460, \"queryPort\": 2461, \"description\": \"Very Hard\", \"icon\": \"immersive.png\" },\n { \"name\": \"Conquest\", \"address\": \"play.forteca.net\", \"port\": 2462, \"queryPort\": 2463, \"description\": \"Kingdoms PvP Warfare\", \"icon\": \"conquest.png\" },\n { \"name\": \"Dominion\", \"address\": \"play.forteca.net\", \"port\": 2464, \"queryPort\": 2465, \"description\": \"Kingdoms PvP Warfare\", \"icon\": \"dominion.png\" },\n { \"name\": \"Builders Heaven\", \"address\": \"play.forteca.net\", \"port\": 2468, \"queryPort\": 2469, \"description\": \"Supporters Creative Mode\", \"icon\": \"buildersheaven.png\" },\n { \"name\": \"Balrond Realm\", \"address\": \"play.forteca.net\", \"port\": 2474, \"queryPort\": 2475, \"description\": \"All Balronds Mods\", \"icon\": \"balrond.png\" },\n { \"name\": \"Aurora III\", \"address\": \"play.forteca.net\", \"port\": 2470, \"queryPort\": 2471, \"description\": \"Adventure - Partner Realm\", \"icon\": \"event.png\" },\n { \"name\": \"Black Ymir\", \"address\": \"play.forteca.net\", \"port\": 2466, \"queryPort\": 2467, \"description\": \"Hard EU\", \"icon\": \"forteca-ymir.png\" },\n { \"name\": \"Test Server\", \"address\": \"play.forteca.net\", \"port\": 2472, \"queryPort\": 2473, \"description\": \"Testing and staging\", \"icon\": \"test-server.png\" }\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 = NormalizeSagaText(ReadString(json, "sagaText", fehuContent.sagaText)), realmsTitle = ReadString(json, "realmsTitle", ReadString(json, "rightTitle", fehuContent.realmsTitle)), servers = new List<FehuServer>(), links = new FehuLinks(), miniPanels = new List<MiniPanelSettings>(), ServerIconSize = ReadInt(json, "ServerIconSize", fehuContent.ServerIconSize), ServerIconSpacing = ReadInt(json, "ServerIconSpacing", fehuContent.ServerIconSpacing) }; fehuContent2.socialPanel = new SocialPanelSettings { Enabled = true, X = -20, Y = 35, Width = 620, Height = 80, IconSize = 42, IconSpacing = 8 }; string 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, "MiniPanels", '[', ']') ?? "", "\\{(?<item>[^{}]*)\\}")) { string value2 = item2.Groups["item"].Value; fehuContent2.miniPanels.Add(new MiniPanelSettings { Enabled = ReadBool(value2, "Enabled", fallback: false), X = ReadInt(value2, "X", 0), Y = ReadInt(value2, "Y", 0), Width = ReadInt(value2, "Width", fehuContent2.socialPanel.Width / 2), Height = ReadInt(value2, "Height", fehuContent2.socialPanel.Height), Icon = ReadString(value2, "Icon", ""), Icons = ReadString(value2, "Icons", ""), Url = ReadString(value2, "Url", ""), Text = ReadString(value2, "Text", "") }); } foreach (Match item3 in Regex.Matches(ReadSection(json, "servers", '[', ']') ?? string.Empty, "\\{(?<server>[^{}]*)\\}")) { string value3 = item3.Groups["server"].Value; int num = ReadInt(value3, "port", 2456); fehuContent2.servers.Add(new FehuServer(ReadString(value3, "name", "Unnamed server"), NormalizeJsonServerAddress(ReadString(value3, "address", string.Empty)), num, string.Empty, string.Empty) { queryPort = ReadInt(value3, "queryPort", num + 1), password = ReadString(value3, "password", string.Empty), description = ReadString(value3, "description", string.Empty), icon = ReadString(value3, "icon", string.Empty), steamIdIcon = false }); } 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 NormalizeJsonServerAddress(string address) { object obj; if (!string.Equals((address ?? string.Empty).Trim(), "forteca.net", StringComparison.OrdinalIgnoreCase)) { obj = address; if (obj == null) { return string.Empty; } } else { obj = "play.forteca.net"; } return (string)obj; } private static string NormalizeSagaText(string value) { if (!string.Equals((value ?? string.Empty).Trim(), "The saga has not begun yet.", StringComparison.OrdinalIgnoreCase)) { return value; } return "Connecting..."; } private static string ReadString(string json, string key, string fallback) { if (json == null) { return fallback; } Match match = Regex.Match(json, "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*\\\"(?<value>(?:\\\\.|[^\\\"])*)\\\""); if (!match.Success) { return fallback; } return Regex.Unescape(match.Groups["value"].Value); } private static int ReadInt(string json, string key, int fallback) { Match match = Regex.Match(json ?? string.Empty, "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*(?<value>-?\\d+)"); if (!match.Success || !int.TryParse(match.Groups["value"].Value, out var result)) { return fallback; } return result; } private static bool ReadBool(string json, string key, bool fallback) { Match match = Regex.Match(json ?? "", "\\\"" + Regex.Escape(key) + "\\\"\\s*:\\s*(?<value>true|false)", RegexOptions.IgnoreCase); if (!match.Success || !bool.TryParse(match.Groups["value"].Value, out var result)) { return fallback; } return result; } private static string ReadSection(string json, string key, char open, char close) { int num = json.IndexOf("\"" + key + "\"", StringComparison.Ordinal); if (num < 0) { return null; } int num2 = json.IndexOf(open, num); if (num2 < 0) { return null; } int num3 = 0; for (int i = num2; i < json.Length; i++) { if (json[i] == open) { num3++; } if (json[i] == close && --num3 == 0) { return json.Substring(num2 + 1, i - num2 - 1); } } return null; } } [Serializable] public sealed class FehuLinks { public string discord; public string website; public string support; } public sealed class FehuMenu : MonoBehaviour { private sealed class SagaFeedEntry { public DateTime TimestampUtc; public string RealmDisplayName; public string Category; public string Title; public string Text; public string Priority; } private sealed class ThemeDefinition { public string Name; public Texture2D Background; public Texture2D Frame; public Texture2D Header; public Texture2D Separator; public Texture2D Button; public Texture2D ButtonHover; public Texture2D ButtonActive; public Texture2D CloseButton; public Texture2D Panel; public Texture2D BottomPanel; public Texture2D Badge; } private sealed class ThemeInfo { public string Name; public string DisplayName; public Color PanelLight; public Color PanelDark; public Color FrameLight; public Color FrameDark; public Color Button; public Color ButtonHover; public Color ButtonActive; public Color Accent; public Color Title; public Color Body; public Color Server; } [CompilerGenerated] private static class _003C_003EO { public static UnityAction _003C1_003E__OpenSupportUrl; } [CompilerGenerated] private static class <>O { public static UnityAction <0>__OpenSupportUrl; } private const float ReferenceWidth = 1920f; private const float ReferenceHeight = 1080f; private ConfigEntry<bool> _enabled; private ConfigEntry<bool> _showOnMainMenu; private ConfigEntry<bool> _hideChangelog; private ConfigEntry<bool> _hideMerchStore; private ConfigEntry<bool> _hideVersionText; private ConfigEntry<bool> _hideModdedWarningText; private ConfigEntry<bool> _hideShowLogButton; private ConfigEntry<bool> _newsEnabled; private ConfigEntry<bool> _sagaEnabled; private ConfigEntry<bool> _realmsEnabled; private ConfigEntry<bool> _otherRealmsEnabled; private ConfigEntry<bool> _socialEnabled; private ConfigEntry<bool> _enablePanelDragging; private ConfigEntry<bool> _enableSteamIdIcons; private ConfigEntry<bool> _enableLiveStatus; private ConfigEntry<int> _rightX; private ConfigEntry<int> _rightY; private ConfigEntry<int> _rightWidth; private ConfigEntry<int> _rightHeight; private ConfigEntry<int> _otherX; private ConfigEntry<int> _otherY; private ConfigEntry<int> _otherWidth; private ConfigEntry<int> _otherHeight; private ConfigEntry<int> _newsX; private ConfigEntry<int> _newsY; private ConfigEntry<int> _newsWidth; private ConfigEntry<int> _newsHeight; private ConfigEntry<int> _sagaX; private ConfigEntry<int> _sagaY; private ConfigEntry<int> _sagaWidth; private ConfigEntry<int> _sagaHeight; private ConfigEntry<int> _socialX; private ConfigEntry<int> _socialY; private ConfigEntry<int> _socialWidth; private ConfigEntry<int> _socialHeight; private ConfigEntry<int> _statusRefreshIntervalSeconds; private ConfigEntry<int> _queryTimeoutMilliseconds; private ConfigEntry<int> _queryRetryCount; private ConfigEntry<int> _retryDelayMilliseconds; private ConfigEntry<int> _initialStaggerMilliseconds; private ConfigEntry<int> _offlineConfirmationCycles; private ConfigEntry<int> _onlineConfirmationCycles; private ConfigEntry<string> _newsTitle; private ConfigEntry<string> _sagaTitle; private ConfigEntry<string> _realmsTitle; private ConfigEntry<string> _otherRealmsTitle; private ConfigEntry<float> _uiScale; private ConfigEntry<string> _themeName; private string _loadedThemeName; private Texture2D _bottomPanel; private ConfigEntry<bool> _showPlayerCounts; private ConfigEntry<bool> _pauseWhenLandingHidden; private ConfigEntry<bool> _logOnlyStateChanges; private ConfigEntry<bool> _debugStatusQueries; private ConfigEntry<bool> _enableLayoutDiagnostics; private ConfigEntry<bool> _keepLastKnownStatusWhileChecking; private ConfigEntry<bool> _bottomLegendEnabled; private ConfigEntry<bool> _leftLegendEnabled; private ConfigEntry<bool> _rightLegendEnabled; private ConfigEntry<bool> _legendF1Enabled; private ConfigEntry<bool> _legendF3Enabled; private ConfigEntry<bool> _legendF4Enabled; private ConfigEntry<bool> _legendF6Enabled; private ConfigEntry<bool> _legendF7Enabled; private ConfigEntry<bool> _legendF8Enabled; private ConfigEntry<bool> _legendF9Enabled; private ConfigEntry<bool> _legendF10Enabled; private ConfigEntry<bool> _steamIdLegendEnabled; private ConfigEntry<bool> _joinLegendEnabled; private ConfigEntry<string> _legendF1Label; private ConfigEntry<string> _legendF3Label; private ConfigEntry<string> _legendF4Label; private ConfigEntry<string> _legendF6Label; private ConfigEntry<string> _legendF7Label; private ConfigEntry<string> _legendF8Label; private ConfigEntry<string> _legendF9Label; private ConfigEntry<string> _legendF10Label; private ConfigEntry<string> _steamIdLegendLabel; private ConfigEntry<string> _steamIdLegendText; private ConfigEntry<string> _joinLegendTitle; private ConfigEntry<string> _joinLegendText; private ConfigEntry<int> _socialIconSize; private ConfigEntry<int> _socialIconSpacing; private ConfigEntry<int> _bottomLeftLegendX; private ConfigEntry<int> _bottomLeftLegendY; private ConfigEntry<int> _bottomRightLegendX; private ConfigEntry<int> _bottomRightLegendY; private ConfigEntry<bool>[] _miniEnabled; private ConfigEntry<int>[] _miniX; private ConfigEntry<int>[] _miniY; private ConfigEntry<int>[] _miniWidth; private ConfigEntry<int>[] _miniHeight; private ConfigEntry<string>[] _miniText; private ConfigEntry<string>[] _miniIcons; private ConfigEntry<string>[] _miniUrl; private FehuContent _content; private string _contentPath; private bool _hiddenForSession; private bool _topLeftVisible = true; private bool _bottomLeftVisible = true; private bool _topRightVisible = true; private bool _bottomRightVisible = true; private bool _bottomLeftLegendVisible = true; private bool _bottomRightLegendVisible = true; private bool _socialVisible = true; private bool _themeSelectorVisible; private string _pendingThemeName; private readonly bool[] _miniVisible = new bool[3] { true, true, true }; private string _dragPanelId; private Vector2 _dragOffset; private Vector2 _newsScroll; private Vector2 _sagaScroll; private GUIStyle _titleStyle; private GUIStyle _bodyStyle; private GUIStyle _serverStyle; private GUIStyle _buttonStyle; private Texture2D _parchment; private Texture2D _ink; private Texture2D _gold; private Texture2D _fade; private Texture2D _joinIcon; private Texture2D _copyIpIcon; private Texture2D _onlineIcon; private Texture2D _offlineIcon; private Texture2D _checkIcon; private Texture2D _steamIdIcon; private readonly HashSet<string> _hiddenLog = new HashSet<string>(); private readonly HashSet<string> _socialIconLog = new HashSet<string>(); private readonly Dictionary<string, Texture2D> _socialIcons = new Dictionary<string, Texture2D>(); private readonly Dictionary<string, Texture2D> _assetIcons = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> _missingStatusIcons = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> _missingDrawTextureLog = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, ConfigEntry<bool>> _serverSteamIdIconEntries = new Dictionary<string, ConfigEntry<bool>>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, ServerRuntimeState> _serverStates = new Dictionary<string, ServerRuntimeState>(); private readonly Dictionary<string, string> _lastQueryFailureLog = new Dictionary<string, string>(); private readonly Dictionary<string, DateTime> _lastLogUtc = new Dictionary<string, DateTime>(); private readonly Dictionary<string, int> _realmDescriptionFontSizeCache = new Dictionary<string, int>(StringComparer.Ordinal); private readonly Dictionary<string, string[]> _serverDescriptionLinesCache = new Dictionary<string, string[]>(StringComparer.Ordinal); private readonly Dictionary<string, string[]> _miniIconListCache = new Dictionary<string, string[]>(StringComparer.Ordinal); private readonly List<FehuServer> _fehuRealmServers = new List<FehuServer>(); private readonly List<FehuServer> _otherRealmServers = new List<FehuServer>(); private readonly List<SagaFeedEntry> _chronicleEntries = new List<SagaFeedEntry>(); private readonly float[] _shortcutEntryWidths = new float[8]; private readonly int[] _shortcutEntryIndexes = new int[8]; private readonly GUIContent _measureContent = new GUIContent(); private ConfigEntry<bool>[] _leftShortcutEnabled; private ConfigEntry<string>[] _leftShortcutLabels; private ConfigEntry<bool>[] _rightShortcutEnabled; private ConfigEntry<string>[] _rightShortcutLabels; private static readonly string[] LeftShortcutIcons = new string[4] { "theme.png", "empty1.png", "empty2.png", "f7.png" }; private static readonly string[] LeftShortcutDefaults = new string[4] { string.Empty, string.Empty, string.Empty, "Toggle UI" }; private static readonly string[] RightShortcutIcons = new string[8] { "f1.png", "f3.png", "f4.png", "f6.png", "f8.png", "f9.png", "f10.png", "free.png" }; private static readonly string[] RightShortcutDefaults = new string[8] { "Configs", "Kingdoms", "Vault", "Rumble", "Arena", "Rewards", "Factions", "Free" }; private static readonly string[] MainRealmDescriptionLines = new string[3] { "The Eternal Realm", "One Save To Rule Them All", "Market • Settlement" }; private static readonly string[] ActiveThemeNames = new string[4] { "Classic", "Vanilla", "Runestone", "DarkIron" }; private static readonly ThemeInfo[] ThemeRegistry = new ThemeInfo[10] { Theme("Classic", "Classic", new Color(0.92f, 0.68f, 0.32f, 0.92f), new Color(0.52f, 0.26f, 0.08f, 0.94f), new Color(0.82f, 0.48f, 0.16f, 0.96f), new Color(0.34f, 0.16f, 0.05f, 0.96f), new Color(0.1f, 0.055f, 0.025f, 0.85f), new Color(0.48f, 0.19f, 0.035f, 0.75f), new Color(0.56f, 0.24f, 0.06f, 0.88f), new Color(0.48f, 0.19f, 0.035f, 0.75f), new Color(0.55f, 0.18f, 0.025f), new Color(0.16f, 0.075f, 0.03f), new Color(0.4f, 0.13f, 0.02f)), Theme("Vanilla", "Vanilla", new Color(0.13f, 0.09f, 0.06f, 0.97f), new Color(0.025f, 0.022f, 0.019f, 0.98f), new Color(0.26f, 0.16f, 0.08f, 1f), new Color(0.04f, 0.032f, 0.025f, 1f), new Color(0.035f, 0.028f, 0.024f, 0.96f), new Color(0.24f, 0.14f, 0.055f, 0.98f), new Color(0.32f, 0.18f, 0.07f, 0.98f), new Color(0.78f, 0.46f, 0.18f, 0.76f), new Color(0.93f, 0.74f, 0.42f), new Color(0.9f, 0.82f, 0.66f), new Color(1f, 0.84f, 0.48f)), Theme("Nordic", "Nordic", new Color(0.18f, 0.24f, 0.29f, 0.96f), new Color(0.035f, 0.055f, 0.075f, 0.98f), new Color(0.38f, 0.48f, 0.56f, 1f), new Color(0.07f, 0.1f, 0.13f, 1f), new Color(0.055f, 0.075f, 0.095f, 0.96f), new Color(0.2f, 0.3f, 0.38f, 0.98f), new Color(0.26f, 0.38f, 0.48f, 0.98f), new Color(0.42f, 0.66f, 0.86f, 0.76f), new Color(0.78f, 0.88f, 0.95f), new Color(0.8f, 0.86f, 0.9f), new Color(0.7f, 0.86f, 1f)), Theme("Valheim", "Valheim", new Color(0.18f, 0.11f, 0.055f, 0.96f), new Color(0.035f, 0.026f, 0.018f, 0.98f), new Color(0.48f, 0.3f, 0.11f, 1f), new Color(0.07f, 0.045f, 0.025f, 1f), new Color(0.05f, 0.035f, 0.022f, 0.96f), new Color(0.3f, 0.17f, 0.055f, 0.98f), new Color(0.42f, 0.22f, 0.07f, 0.98f), new Color(0.9f, 0.52f, 0.16f, 0.76f), new Color(0.95f, 0.72f, 0.36f), new Color(0.88f, 0.78f, 0.6f), new Color(1f, 0.76f, 0.36f)), Theme("DarkIron", "Dark Iron", new Color(0.11f, 0.105f, 0.1f, 0.97f), new Color(0.012f, 0.012f, 0.014f, 0.99f), new Color(0.36f, 0.33f, 0.3f, 1f), new Color(0.035f, 0.035f, 0.04f, 1f), new Color(0.025f, 0.024f, 0.026f, 0.97f), new Color(0.3f, 0.16f, 0.045f, 0.98f), new Color(0.48f, 0.22f, 0.055f, 0.98f), new Color(1f, 0.46f, 0.11f, 0.78f), new Color(1f, 0.66f, 0.28f), new Color(0.82f, 0.78f, 0.7f), new Color(1f, 0.58f, 0.2f)), Theme("Runestone", "Runestone", new Color(0.2f, 0.21f, 0.22f, 0.96f), new Color(0.045f, 0.048f, 0.052f, 0.98f), new Color(0.44f, 0.46f, 0.48f, 1f), new Color(0.08f, 0.085f, 0.09f, 1f), new Color(0.045f, 0.048f, 0.052f, 0.96f), new Color(0.12f, 0.22f, 0.32f, 0.98f), new Color(0.16f, 0.3f, 0.44f, 0.98f), new Color(0.36f, 0.7f, 1f, 0.7f), new Color(0.72f, 0.84f, 0.94f), new Color(0.8f, 0.82f, 0.8f), new Color(0.6f, 0.82f, 1f)), Theme("Frost", "Frost", new Color(0.5f, 0.62f, 0.68f, 0.94f), new Color(0.12f, 0.18f, 0.22f, 0.97f), new Color(0.72f, 0.82f, 0.88f, 1f), new Color(0.2f, 0.28f, 0.34f, 1f), new Color(0.12f, 0.18f, 0.22f, 0.96f), new Color(0.36f, 0.52f, 0.62f, 0.98f), new Color(0.48f, 0.64f, 0.74f, 0.98f), new Color(0.68f, 0.9f, 1f, 0.76f), new Color(0.9f, 0.97f, 1f), new Color(0.88f, 0.94f, 0.96f), new Color(0.8f, 0.96f, 1f)), Theme("Ember", "Ember", new Color(0.24f, 0.075f, 0.035f, 0.96f), new Color(0.045f, 0.018f, 0.012f, 0.98f), new Color(0.68f, 0.2f, 0.06f, 1f), new Color(0.11f, 0.035f, 0.018f, 1f), new Color(0.06f, 0.022f, 0.012f, 0.96f), new Color(0.42f, 0.11f, 0.032f, 0.98f), new Color(0.64f, 0.16f, 0.04f, 0.98f), new Color(1f, 0.34f, 0.08f, 0.78f), new Color(1f, 0.64f, 0.28f), new Color(0.94f, 0.78f, 0.62f), new Color(1f, 0.48f, 0.16f)), Theme("Royal", "Royal", new Color(0.055f, 0.085f, 0.2f, 0.96f), new Color(0.018f, 0.022f, 0.055f, 0.98f), new Color(0.72f, 0.56f, 0.2f, 1f), new Color(0.08f, 0.06f, 0.12f, 1f), new Color(0.025f, 0.03f, 0.08f, 0.96f), new Color(0.16f, 0.13f, 0.32f, 0.98f), new Color(0.26f, 0.18f, 0.42f, 0.98f), new Color(0.95f, 0.72f, 0.28f, 0.78f), new Color(1f, 0.82f, 0.38f), new Color(0.86f, 0.86f, 0.96f), new Color(1f, 0.8f, 0.36f)), Theme("Ancient", "Ancient", new Color(0.18f, 0.22f, 0.16f, 0.96f), new Color(0.045f, 0.055f, 0.04f, 0.98f), new Color(0.45f, 0.42f, 0.28f, 1f), new Color(0.08f, 0.09f, 0.065f, 1f), new Color(0.045f, 0.055f, 0.04f, 0.96f), new Color(0.18f, 0.28f, 0.16f, 0.98f), new Color(0.26f, 0.38f, 0.22f, 0.98f), new Color(0.42f, 0.7f, 0.38f, 0.76f), new Color(0.82f, 0.82f, 0.6f), new Color(0.82f, 0.86f, 0.7f), new Color(0.62f, 0.84f, 0.46f)) }; private int _lastRealmAutoFitScreenWidth; private int _lastRealmAutoFitScreenHeight; private int _lastRealmAutoFitPanelWidth; private float _lastRealmAutoFitUiScale = -1f; private DateTime _lastServerQueryUtc = DateTime.MinValue; private bool _serverQueriesRunning; private readonly Queue<ServerQueryWorkItem> _serverQueryQueue = new Queue<ServerQueryWorkItem>(); private readonly Dictionary<string, ActiveServerQuery> _activeServerQueries = new Dictionary<string, ActiveServerQuery>(StringComparer.OrdinalIgnoreCase); private readonly List<ActiveServerQuery> _activeServerQueryCancelScratch = new List<ActiveServerQuery>(1); private int _statusGeneration; private ISteamMatchmakingPingResponse _steamPingHandler; private bool _socialIconsLoaded; private bool _liveStatusDisabledLogged; private static readonly bool IsolationI1DisableNativeServerPolling = false; private bool _isolationI1SuppressionLogged; private bool _isolationI1ShutdownLogged; private static readonly bool IsolationI2StaticRuntime = false; private bool _isolationI2StartupLogged; private bool _isolationI2RuntimeLogged; private bool _isolationI2ShutdownLogged; private static readonly bool IsolationI3MinimalShell = false; private bool _isolationI3LoadedLogged; private bool _isolationI3ShutdownLogged; private static readonly bool IsolationI4StartupOnly = false; private bool _isolationI4StartupLogged; private bool _isolationI4ShutdownLogged; private static readonly bool CrashIsolationDiagnosticBuild = false; private ConfigEntry<bool> _isoUIRoot; private ConfigEntry<bool> _isoMainPanels; private ConfigEntry<bool> _isoBottomPanels; private ConfigEntry<bool> _isoServerPanels; private ConfigEntry<bool> _isoChronicleSaga; private ConfigEntry<bool> _isoSocialShortcutPanels; private ConfigEntry<bool> _isoThemeFontsStyles; private ConfigEntry<bool> _isoIconsTexturesSprites; private ConfigEntry<bool> _isoLayoutSetup; private ConfigEntry<bool> _isoSteam; private ConfigEntry<bool> _isoRuntimeSystems; private bool _isolationSettingsLogged; private bool _isolationSceneBuilt; private bool _isolationSceneSkipLogged; private int _isolationTexturesCreated; private int _isolationSpritesCreated; private int _isolationFontsResolved; private int _isolationGuiStylesCreated; private bool _isolationAssetTotalsLogged; private readonly HashSet<string> _isolationGroupsLogged = new HashSet<string>(StringComparer.Ordinal); private GUIStyle _isolationLabelStyle; private GUIStyle _isolationBoxStyle; private readonly Dictionary<string, DateTime> _lastCrashDiagUtcByKey = new Dictionary<string, DateTime>(); private int _queryHandlesCreated; private int _queryHandlesReleased; private int _queryStaleCallbacks; private Texture2D _supportLogo; private Sprite _supportLogoSprite; private readonly HashSet<string> _replacedMerch = new HashSet<string>(); private bool _merchClickBlockedThisMenu; private static readonly bool DisableChronicleRefreshIsolation = false; private static readonly bool DisableAllRuntimeSchedulersIsolation = false; private const string ChronicleRefreshDisabledText = "Chronicle test\nRefresh disabled"; private const string SagaRpcRequestFeed = "FehuChronicles_RequestFeed"; private const string SagaRpcFeed = "FehuChronicles_Feed"; private string _sagaChronicleText; private string _lastSagaLogSignature; private DateTime _lastSagaRpcRequestUtc = DateTime.MinValue; private DateTime _lastSagaFallbackReadUtc = DateTime.MinValue; private bool _sagaRpcRegistered; private bool _chronicleRefreshInProgress; private bool _chronicleWaitingForRpc; private DateTime _nextChronicleRefreshUtc = DateTime.MinValue; private DateTime _chronicleCycleStartedUtc = DateTime.MinValue; private int _chronicleGeneration; private int _chronicleActiveGeneration; private static readonly object[] EmptyRpcArgs = new object[0]; private bool _runtimeSchedulersDisabledLogged; private void Awake() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0097: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_06ea: Unknown result type (might be due to invalid IL or missing references) //IL_06f9: Expected O, but got Unknown //IL_06f4: Unknown result type (might be due to invalid IL or missing references) //IL_06fe: Expected O, but got Unknown //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Expected O, but got Unknown //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_0758: Expected O, but got Unknown if (IsolationI3MinimalShell) { if (!_isolationI3LoadedLogged) { Plugin.Log.LogInfo((object)"[I3] Plugin loaded"); Plugin.Log.LogInfo((object)"[I3] Custom UI creation BYPASSED"); Plugin.Log.LogInfo((object)"[I3] Runtime systems DISABLED"); Plugin.Log.LogInfo((object)"[I3] No FehuLanding assets instantiated"); _isolationI3LoadedLogged = true; } return; } ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config; BindCrashIsolation(config); LogCrashIsolationSettings(); if (!CrashIsolationDiagnosticBuild && !IsolationI4StartupOnly) { _steamPingHandler = new ISteamMatchmakingPingResponse(new ServerResponded(OnSteamPingResponded), new ServerFailedToRespond(OnSteamPingFailed)); } 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", false, (ConfigDescription)null); _hideShowLogButton = config.Bind<bool>("Vanilla Menu", "HideShowLogButton", false, (ConfigDescription)null); _enableLiveStatus = config.Bind<bool>("ServerStatus", "EnableLiveStatus", true, "Enable native live server status queries."); _statusRefreshIntervalSeconds = config.Bind<int>("ServerStatus", "RefreshIntervalSeconds", 60, "Refresh while Landing is visible."); _queryTimeoutMilliseconds = config.Bind<int>("ServerStatus", "QueryTimeoutMilliseconds", 1500, "Maximum time for one Steam query attempt."); _queryRetryCount = config.Bind<int>("ServerStatus", "RetryCount", 1, "Number of additional query-port candidate passes before a server is treated as offline."); _retryDelayMilliseconds = config.Bind<int>("ServerStatus", "RetryDelayMilliseconds", 250, "Short delay before status retry attempts."); _initialStaggerMilliseconds = config.Bind<int>("ServerStatus", "InitialStaggerMilliseconds", 50, "Small delay between starting each server query."); _pauseWhenLandingHidden = config.Bind<bool>("ServerStatus", "PauseWhenLandingHidden", true, "Do not run live polling while Landing is hidden."); _logOnlyStateChanges = config.Bind<bool>("ServerStatus", "LogOnlyStateChanges", true, "Log only live status state changes by default."); _debugStatusQueries = config.Bind<bool>("ServerStatus", "DebugStatusQueries", false, "Detailed query lifecycle diagnostics."); _enableLayoutDiagnostics = config.Bind<bool>("Diagnostics", "EnableLayoutDiagnostics", false, "Enable one-shot/rate-limited layout diagnostics. Disabled by default to prevent render-loop log spam."); _keepLastKnownStatusWhileChecking = config.Bind<bool>("ServerStatus", "KeepLastKnownStatusWhileChecking", true, "Keep green/red status visible while background refresh is checking."); _offlineConfirmationCycles = config.Bind<int>("ServerStatus", "OfflineConfirmationCycles", 2, "Failed query cycles required before showing Offline."); _onlineConfirmationCycles = config.Bind<int>("ServerStatus", "OnlineConfirmationCycles", 1, "Successful query cycles required before showing Online."); _showPlayerCounts = config.Bind<bool>("ServerStatus", "ShowPlayerCounts", true, "Show player counts after successful live status query."); _enableSteamIdIcons = config.Bind<bool>("ServerSteamIdIcons", "EnableSteamIdIcons", true, "Master switch. true = enable SteamID icons system, false = hide all SteamID icons."); BindServerSteamIdIcons(config); _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", "Development Roadmap", (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", 535, (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", 440, (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", 460, (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); if (!IsolationI4StartupOnly) { Plugin.Log.LogInfo((object)"[TheFehu] SocialPanel config applied X/Y/W/H/IconSize/IconSpacing"); } _enablePanelDragging = config.Bind<bool>("General", "EnablePanelDragging", true, "Hold CTRL and drag FehuLanding panels to save their X/Y position."); BindMiniPanels(config); BindBottomLegend(config); InitializeShortcutLegendCaches(); BindRealmLegend(config); if (_newsTitle.Value == "Announcements") { _newsTitle.Value = "Development Roadmap"; config.Save(); } _uiScale = config.Bind<float>("General", "UIScale", 1f, new ConfigDescription("Additional UI scale.", (AcceptableValueBase)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); _themeName = config.Bind<string>("Appearance", "Theme", "Classic", new ConfigDescription("Visual theme. Invalid values fall back to Classic.", (AcceptableValueBase)new AcceptableValueList<string>(new string[4] { "Classic", "Vanilla", "Runestone", "DarkIron" }), Array.Empty<object>())); _contentPath = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "FehuLanding.json"); if (IsolationI4StartupOnly && !_isolationI4StartupLogged) { Plugin.Log.LogInfo((object)"[I4] Config initialized"); } LoadContent(); if (IsolationI4StartupOnly && !_isolationI4StartupLogged) { Plugin.Log.LogInfo((object)"[I4] JSON initialized"); } if (IsolationI2StaticRuntime && !_isolationI2StartupLogged) { Plugin.Log.LogInfo((object)"[I2] Static UI initialized"); Plugin.Log.LogInfo((object)"[I2] Background refresh DISABLED"); Plugin.Log.LogInfo((object)"[I2] AutoFit DISABLED"); Plugin.Log.LogInfo((object)"[I2] Runtime layout refresh DISABLED"); _isolationI2StartupLogged = true; } SceneManager.sceneLoaded += OnSceneLoaded; if (IsolationI4StartupOnly && !_isolationI4StartupLogged) { Plugin.Log.LogInfo((object)"[I4] Scene subscription initialized"); Plugin.Log.LogInfo((object)"[I4] Steam systems DISABLED"); Plugin.Log.LogInfo((object)"[I4] UI and assets BYPASSED"); Plugin.Log.LogInfo((object)"[I4] Runtime systems DISABLED"); _isolationI4StartupLogged = true; } } private void OnDestroy() { if (IsolationI3MinimalShell) { if (!_isolationI3ShutdownLogged) { Plugin.Log.LogInfo((object)"[I3] shutdown/disable reached"); _isolationI3ShutdownLogged = true; } return; } SceneManager.sceneLoaded -= OnSceneLoaded; if (IsolationI4StartupOnly) { if (!_isolationI4ShutdownLogged) { Plugin.Log.LogInfo((object)"[I4] shutdown/disable reached"); _isolationI4ShutdownLogged = true; } return; } if (IsolationI1DisableNativeServerPolling && !_isolationI1ShutdownLogged) { Plugin.Log.LogInfo((object)"[FehuLanding] I1 shutdown/disable reached"); _isolationI1ShutdownLogged = true; } if (IsolationI2StaticRuntime && !_isolationI2ShutdownLogged) { Plugin.Log.LogInfo((object)"[I2] shutdown/disable reached"); _isolationI2ShutdownLogged = true; } if (CrashIsolationDiagnosticBuild) { DestroyIsolationOwnedObjects(); } else { CancelAllServerQueries("destroy"); } } private void BindCrashIsolation(ConfigFile config) { _isoUIRoot = config.Bind<bool>("Crash Isolation", "IsolationEnableUIRoot", false, (ConfigDescription)null); _isoMainPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableMainPanels", false, (ConfigDescription)null); _isoBottomPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableBottomPanels", false, (ConfigDescription)null); _isoServerPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableServerPanels", false, (ConfigDescription)null); _isoChronicleSaga = config.Bind<bool>("Crash Isolation", "IsolationEnableChronicleSaga", false, (ConfigDescription)null); _isoSocialShortcutPanels = config.Bind<bool>("Crash Isolation", "IsolationEnableSocialShortcutPanels", false, (ConfigDescription)null); _isoThemeFontsStyles = config.Bind<bool>("Crash Isolation", "IsolationEnableThemeFontsStyles", false, (ConfigDescription)null); _isoIconsTexturesSprites = config.Bind<bool>("Crash Isolation", "IsolationEnableIconsTexturesSprites", false, (ConfigDescription)null); _isoLayoutSetup = config.Bind<bool>("Crash Isolation", "IsolationEnableLayoutSetup", false, (ConfigDescription)null); _isoSteam = config.Bind<bool>("Crash Isolation", "IsolationEnableSteam", false, (ConfigDescription)null); _isoRuntimeSystems = config.Bind<bool>("Crash Isolation", "IsolationEnableRuntimeSystems", false, (ConfigDescription)null); } private static bool Iso(ConfigEntry<bool> entry) { return entry?.Value ?? false; } private void LogCrashIsolationSettings() { if (CrashIsolationDiagnosticBuild && !_isolationSettingsLogged) { Plugin.Log.LogInfo((object)"[Isolation] Diagnostic UI build active"); Plugin.Log.LogInfo((object)("[Isolation] UIRoot=" + Iso(_isoUIRoot))); Plugin.Log.LogInfo((object)("[Isolation] MainPanels=" + Iso(_isoMainPanels))); Plugin.Log.LogInfo((object)("[Isolation] BottomPanels=" + Iso(_isoBottomPanels))); Plugin.Log.LogInfo((object)("[Isolation] ServerPanels=" + Iso(_isoServerPanels))); Plugin.Log.LogInfo((object)("[Isolation] ChronicleSaga=" + Iso(_isoChronicleSaga))); Plugin.Log.LogInfo((object)("[Isolation] SocialShortcutPanels=" + Iso(_isoSocialShortcutPanels))); Plugin.Log.LogInfo((object)("[Isolation] ThemeFontsStyles=" + Iso(_isoThemeFontsStyles))); Plugin.Log.LogInfo((object)("[Isolation] IconsTexturesSprites=" + Iso(_isoIconsTexturesSprites))); Plugin.Log.LogInfo((object)("[Isolation] LayoutSetup=" + Iso(_isoLayoutSetup))); Plugin.Log.LogInfo((object)("[Isolation] Steam=" + Iso(_isoSteam))); Plugin.Log.LogInfo((object)("[Isolation] RuntimeSystems=" + Iso(_isoRuntimeSystems))); _isolationSettingsLogged = true; } } private void BuildIsolationSceneOnce() { if (_isolationSceneBuilt) { if (!_isolationSceneSkipLogged) { Plugin.Log.LogInfo((object)"[Isolation] Scene construction skipped; already initialized"); _isolationSceneSkipLogged = true; } } else { _isolationSceneBuilt = true; } } private void DestroyIsolationOwnedObjects() { _isolationSceneBuilt = false; } private void LogIsolationWarningOnce(string key, string message) { if (_isolationGroupsLogged.Add("warn:" + key)) { Plugin.Log.LogWarning((object)message); } } private void LogIsolationGroup(string groupName, Action action) { Stopwatch stopwatch = Stopwatch.StartNew(); bool flag = false; bool flag2 = _isolationGroupsLogged.Add(groupName); if (flag2) { Plugin.Log.LogInfo((object)("[Isolation] BEGIN " + groupName)); } try { action?.Invoke(); flag = true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Isolation] " + groupName + " failed: " + ex)); } finally { stopwatch.Stop(); if (flag2) { Plugin.Log.LogInfo((object)("[Isolation] END " + groupName + " success=" + flag + " elapsedMs=" + stopwatch.ElapsedMilliseconds)); } } } private void EnsureIsolationStyles() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if (_isolationLabelStyle == null || _isolationBoxStyle == null) { _isolationLabelStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, alignment = (TextAnchor)0, wordWrap = true }; _isolationBoxStyle = new GUIStyle(GUI.skin.box) { fontSize = 14, alignment = (TextAnchor)4 }; _isolationGuiStylesCreated += 2; _isolationFontsResolved++; } } private void DrawCrashIsolationDiagnosticUi() { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) if (!IsMainMenu() || !Iso(_isoUIRoot)) { return; } if (_content == null) { LoadContent(); } if (NeedsThemeBuild()) { if (!Iso(_isoThemeFontsStyles)) { if (Iso(_isoMainPanels) || Iso(_isoBottomPanels) || Iso(_isoServerPanels) || Iso(_isoChronicleSaga) || Iso(_isoSocialShortcutPanels)) { LogIsolationWarningOnce("ThemeFontsStylesDependency", "[Isolation] Production visual groups bypassed because IsolationEnableThemeFontsStyles=false"); } return; } LogIsolationGroup("ThemeFontsStyles", delegate { BuildTheme(); }); } float num = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * _uiScale.Value; num = Mathf.Max(0.35f, num); Matrix4x4 matrix = GUI.matrix; int depth = GUI.depth; GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)); GUI.depth = -1000; float num2 = (float)Screen.width / num; float logicalHeight = (float)Screen.height / num; if (Iso(_isoMainPanels) && _newsEnabled.Value && _topLeftVisible) { LogIsolationGroup("MainPanels", delegate { //IL_009d: Unknown result type (might be due to invalid IL or missing references) Rect panel = default(Rect); ((Rect)(ref panel))..ctor((float)_newsX.Value, (float)_newsY.Value, (float)_newsWidth.Value, (float)_newsHeight.Value); if (Iso(_isoLayoutSetup)) { HandlePanelDrag("TopLeft", ref panel, _newsX, _newsY, rightAnchored: false, num2, logicalHeight); } DrawStoryBoard("TopLeft", panel, string.IsNullOrEmpty(_newsTitle.Value) ? _content.newsTitle : _newsTitle.Value, _content.newsText, ref _newsScroll, ref _topLeftVisible); }); } if (Iso(_isoChronicleSaga) && _sagaEnabled.Value && _bottomLeftVisible) { LogIsolationGroup("ChronicleSaga", delegate { //IL_009d: Unknown result type (might be due to invalid IL or missing references) Rect panel = default(Rect); ((Rect)(ref panel))..ctor((float)_sagaX.Value, (float)_sagaY.Value, (float)_sagaWidth.Value, (float)_sagaHeight.Value); if (Iso(_isoLayoutSetup)) { HandlePanelDrag("BottomLeft", ref panel, _sagaX, _sagaY, rightAnchored: false, num2, logicalHeight); } DrawChronicleBoard("BottomLeft", panel, string.IsNullOrEmpty(_sagaTitle.Value) ? _content.sagaTitle : _sagaTitle.Value, ref _sagaScroll, ref _bottomLeftVisible); }); } if (Iso(_isoServerPanels)) { LogIsolationGroup("ServerPanels", delegate { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) if (_realmsEnabled.Value && _topRightVisible) { Rect panel = default(Rect); ((Rect)(ref panel))..ctor(num2 - (float)_rightWidth.Value + (float)_rightX.Value, (float)_rightY.Value, (float)_rightWidth.Value, (float)_rightHeight.Value); if (Iso(_isoLayoutSetup)) { HandlePanelDrag("TopRight", ref panel, _rightX, _rightY, rightAnchored: true, num2, logicalHeight); } DrawRealmsBoard("TopRight", panel, string.IsNullOrEmpty(_realmsTitle.Value) ? _content.realmsTitle : _realmsTitle.Value, _fehuRealmServers, ref _topRightVisible, fehuRealm: true); } if (_otherRealmsEnabled.Value && _bottomRightVisible) { Rect panel2 = default(Rect); ((Rect)(ref panel2))..ctor(num2 - (float)_otherWidth.Value + (float)_otherX.Value, (float)_otherY.Value, (float)_otherWidth.Value, (float)_otherHeight.Value); if (Iso(_isoLayoutSetup)) { HandlePanelDrag("BottomRight", ref panel2, _otherX, _otherY, rightAnchored: true, num2, logicalHeight); } DrawRealmsBoard("BottomRight", panel2, _otherRealmsTitle.Value, _otherRealmServers, ref _bottomRightVisible, fehuRealm: false); } }); } if (Iso(_isoSocialShortcutPanels)) { LogIsolationGroup("SocialShortcutPanels", delegate { //IL_013a: Unknown result type (might be due to invalid IL or missing references) SocialPanelSettings socialPanelSettings = new SocialPanelSettings { Enabled = _socialEnabled.Value, X = _socialX.Value, Y = _socialY.Value, Width = _socialWidth.Value, Height = _socialHeight.Value, IconSize = _socialIconSize.Value, IconSpacing = _socialIconSpacing.Value }; if (socialPanelSettings.Enabled && _socialVisible) { Rect panel = default(Rect); ((Rect)(ref panel))..ctor(num2 - (float)socialPanelSettings.Width + (float)socialPanelSettings.X, (float)socialPanelSettings.Y, (float)socialPanelSettings.Width, (float)socialPanelSettings.Height); if (Iso(_isoLayoutSetup)) { HandlePanelDrag("Social", ref panel, _socialX, _socialY, rightAnchored: true, num2, logicalHeight); } DrawSocial(panel, socialPanelSettings); } DrawMiniPanels(num2, logicalHeight); }); } if (Iso(_isoBottomPanels)) { LogIsolationGroup("BottomPanels", delegate { DrawBottomLegend(num2, logicalHeight); }); } GUI.matrix = matrix; GUI.depth = depth; if (!_isolationAssetTotalsLogged) { Plugin.Log.LogInfo((object)("[Isolation Assets] Texture2D created=" + _isolationTexturesCreated)); Plugin.Log.LogInfo((object)("[Isolation Assets] Sprites created=" + _isolationSpritesCreated)); Plugin.Log.LogInfo((object)("[Isolation Assets] Fonts resolved=" + _isolationFontsResolved)); Plugin.Log.LogInfo((object)("[Isolation Assets] GUIStyles created=" + _isolationGuiStylesCreated)); _isolationAssetTotalsLogged = true; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (IsolationI3MinimalShell || IsolationI4StartupOnly) { return; } if (CrashIsolationDiagnosticBuild) { if (IsMainMenu()) { _hiddenForSession = false; _topLeftVisible = (_bottomLeftVisible = (_topRightVisible = (_bottomRightVisible = (_socialVisible = true)))); SetAllMiniVisible(visible: true); if (!_isolationSceneSkipLogged) { Plugin.Log.LogInfo((object)"[Isolation] Main menu entered; production UI groups are controlled by Crash Isolation switches"); _isolationSceneSkipLogged = true; } } } else if (IsMainMenu()) { _hiddenForSession = false; _topLeftVisible = (_bottomLeftVisible = (_topRightVisible = (_bottomRightVisible = (_socialVisible = true)))); SetAllMiniVisible(visible: true); _merchClickBlockedThisMenu = false; } } private IEnumerator MerchDiscoveryAfterLoad() { yield return (object)new WaitForSeconds(1f); LogMerchCandidates(); } private IEnumerator HideVanillaMenuAfterLoad() { HideVanillaMenu(); yield return (object)new WaitForSeconds(0.5f); HideVanillaMenu(); yield return (object)new WaitForSeconds(0.5f); HideVanillaMenu(); yield return (object)new WaitForSeconds(2f); HideVanillaMenu(); yield return (object)new WaitForSeconds(2f); HideVanillaMenu(); } private void Update() { if (IsolationI3MinimalShell || IsolationI4StartupOnly || (CrashIsolationDiagnosticBuild && !Iso(_isoRuntimeSystems))) { return; } if (Input.GetKeyDown((KeyCode)288) && IsMainMenu()) { ToggleLandingTabs(); if (_hiddenForSession && (_pauseWhenLandingHidden == null || _pauseWhenLandingHidden.Value)) { CancelAllServerQueries("landing hidden"); } Plugin.Log.LogInfo((object)"[FehuLanding] F7 toggle Landing tabs"); } if (DisableAllRuntimeSchedulersIsolation) { if (!_runtimeSchedulersDisabledLogged) { Plugin.Log.LogInfo((object)"[Isolation] Runtime schedulers disabled."); _runtimeSchedulersDisabledLogged = true; } } else if (IsMainMenu()) { if (IsolationI2StaticRuntime) { if (!_isolationI2RuntimeLogged) { Plugin.Log.LogInfo((object)"[I2] Runtime background refresh suppressed"); _isolationI2RuntimeLogged = true; } return; } if (_hiddenForSession && (_pauseWhenLandingHidden == null || _pauseWhenLandingHidden.Value)) { CancelAllServerQueries("landing hidden"); } else { BeginServerQueriesIfNeeded(); if (!IsolationI1DisableNativeServerPolling) { CheckActiveServerQueryTimeout(); PumpSteamServerQuery(); } } if (!DisableChronicleRefreshIsolation) { RunChronicleScheduler(); } } else if (_serverQueriesRunning || _activeServerQueries.Count > 0) { CancelAllServerQueries("left main menu"); } } private void OnGUI() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) if (IsolationI3MinimalShell || IsolationI4StartupOnly) { return; } if (CrashIsolationDiagnosticBuild) { DrawCrashIsolationDiagnosticUi(); } else if (_enabled.Value && _showOnMainMenu.Value && !_hiddenForSession && IsMainMenu()) { if (_content == null) { LoadContent(); } if (_titleStyle == null) { BuildTheme(); BlockMerchStoreClickOnce(); } float num = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * _uiScale.Value; num = Mathf.Max(0.35f, num); Matrix4x4 matrix = GUI.matrix; int depth = GUI.depth; GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)); GUI.depth = -1000; float num2 = (float)Screen.width / num; float logicalHeight = (float)Screen.height / num; if (_newsEnabled.Value && _topLeftVisible) { Rect panel = default(Rect); ((Rect)(ref panel))..ctor((float)_newsX.Value, (float)_newsY.Value, (float)_newsWidth.Value, (float)_newsHeight.Value); HandlePanelDrag("TopLeft", ref panel, _newsX, _newsY, rightAnchored: false, num2, logicalHeight); DrawStoryBoard("TopLeft", panel, string.IsNullOrEmpty(_newsTitle.Value) ? _content.newsTitle : _newsTitle.Value, _content.newsText, ref _newsScroll, ref _topLeftVisible); } if (_sagaEnabled.Value && _bottomLeftVisible) { Rect panel2 = default(Rect); ((Rect)(ref panel2))..ctor((float)_sagaX.Value, (float)_sagaY.Value, (float)_sagaWidth.Value, (float)_sagaHeight.Value); HandlePanelDrag("BottomLeft", ref panel2, _sagaX, _sagaY, rightAnchored: false, num2, logicalHeight); DrawChronicleBoard("BottomLeft", panel2, string.IsNullOrEmpty(_sagaTitle.Value) ? _content.sagaTitle : _sagaTitle.Value, ref _sagaScroll, ref _bottomLeftVisible); } if (_realmsEnabled.Value && _topRightVisible) { Rect panel3 = default(Rect); ((Rect)(ref panel3))..ctor(num2 - (float)_rightWidth.Value + (float)_rightX.Value, (float)_rightY.Value, (float)_rightWidth.Value, (float)_rightHeight.Value); HandlePanelDrag("TopRight", ref panel3, _rightX, _rightY, rightAnchored: true, num2, logicalHeight); DrawRealmsBoard("TopRight", panel3, string.IsNullOrEmpty(_realmsTitle.Value) ? _content.realmsTitle : _realmsTitle.Value, _fehuRealmServers, ref _topRightVisible, fehuRealm: true); } if (_otherRealmsEnabled.Value && _bottomRightVisible) { Rect panel4 = default(Rect); ((Rect)(ref panel4))..ctor(num2 - (float)_otherWidth.Value + (float)_otherX.Value, (float)_otherY.Value, (float)_otherWidth.Value, (float)_otherHeight.Value); HandlePanelDrag("BottomRight", ref panel4, _otherX, _otherY, rightAnchored: true, num2, logicalHeight); DrawRealmsBoard("BottomRight", panel4, _otherRealmsTitle.Value, _otherRealmServers, ref _bottomRightVisible, fehuRealm: false); } SocialPanelSettings socialPanelSettings = new SocialPanelSettings { Enabled = _socialEnabled.Value, X = _socialX.Value, Y = _socialY.Value, Width = _socialWidth.Value, Height = _socialHeight.Value, IconSize = _socialIconSize.Value, IconSpacing = _socialIconSpacing.Value }; if (socialPanelSettings.Enabled && _socialVisible) { Rect panel5 = default(Rect); ((Rect)(ref panel5))..ctor(num2 - (float)socialPanelSettings.Width + (float)socialPanelSettings.X, (float)socialPanelSettings.Y, (float)socialPanelSettings.Width, (float)socialPanelSettings.Height); HandlePanelDrag("Social", ref panel5, _socialX, _socialY, rightAnchored: true, num2, logicalHeight); DrawSocial(panel5, socialPanelSettings); } DrawMiniPanels(num2, logicalHeight); DrawBottomLegend(num2, logicalHeight); GUI.matrix = matrix; GUI.depth = depth; } } private string GetSagaChronicleText() { if (DisableChronicleRefreshIsolation) { return "Chronicle test\nRefresh disabled"; } if (!string.IsNullOrWhiteSpace(_sagaChronicleText)) { return _sagaChronicleText; } return _content.sagaText; } private void RunChronicleScheduler() { TryRegisterSagaRpc(); DateTime utcNow = DateTime.UtcNow; if (_chronicleRefreshInProgress) { if (_chronicleWaitingForRpc && (utcNow - _chronicleCycleStartedUtc).TotalSeconds >= 2.0) { ReadSagaFeedFallbackOnce(); FinishChronicleRefresh("fallback-after-rpc-timeout"); } else if ((utcNow - _chronicleCycleStartedUtc).TotalSeconds >= 5.0) { FinishChronicleRefresh("timeout"); } } else if (!(utcNow < _nextChronicleRefreshUtc)) { StartChronicleRefreshCycle(); } } private void StartChronicleRefreshCycle() { _chronicleRefreshInProgress = true; _chronicleWaitingForRpc = false; _chronicleCycleStartedUtc = DateTime.UtcNow; _chronicleGeneration++; _chronicleActiveGeneration = _chronicleGeneration; Plugin.Log.LogInfo((object)"[FehuLanding] Chronicle refresh started"); if (_sagaRpcRegistered && ZRoutedRpc.instance != null) { try { _lastSagaRpcRequestUtc = DateTime.UtcNow; _chronicleWaitingForRpc = true; ZRoutedRpc.instance.InvokeRoutedRPC("FehuChronicles_RequestFeed", EmptyRpcArgs); return; } catch (Exception ex) { LogChronicleRefreshFailure("RPC request unavailable: " + ex.Message); } } ReadSagaFeedFallbackOnce(); FinishChronicleRefresh("fallback"); } private void FinishChronicleRefresh(string reason) { _chronicleRefreshInProgress = false; _chronicleWaitingForRpc = false; _nextChronicleRefreshUtc = DateTime.UtcNow.AddSeconds(30.0); Plugin.Log.LogInfo((object)("[FehuLanding] Chronicle refresh completed: " + reason)); } private void TryRegisterSagaRpc() { if (_sagaRpcRegistered || ZRoutedRpc.instance == null) { return; } try { ZRoutedRpc.instance.Register<string>("FehuChronicles_Feed", (Action<long, string>)OnSagaFeedRpc); _sagaRpcRegistered = true; Plugin.Log.LogInfo((object)"[FehuLanding] SkaldSaga RPC receiver registered: FehuChronicles_Feed"); } catch (Exception ex) { LogChronicleRefreshFailure("RPC receiver failed: " + ex.Message); } } private void RequestSagaFeedIfNeeded() { if (!_chronicleRefreshInProgress) { StartChronicleRefreshCycle(); } } private void OnSagaFeedRpc(long sender, string json) { if (!DisableChronicleRefreshIsolation) { if (!_chronicleRefreshInProgress || !_chronicleWaitingForRpc) { Plugin.Log.LogInfo((object)"[FehuLanding] Chronicle stale RPC response ignored"); return; } ApplySagaFeedJson(json, 10); FinishChronicleRefresh("rpc"); } } private void ReadSagaFeedFallbackIfNeeded() { if (!_chronicleRefreshInProgress) { StartChronicleRefreshCycle(); } } private void ReadSagaFeedFallbackOnce() { _lastSagaFallbackReadUtc = DateTime.UtcNow; try { string path = Path.Combine(Paths.ConfigPath, "FehuChronicles", "SagaFeed.json"); if (File.Exists(path)) { ApplySagaFeedJson(File.ReadAllText(path), 10); } } catch (Exception ex) { LogChronicleRefreshFailure("SagaFeed fallback failed: " + ex.Message); } } private bool ApplySagaFeedJson(string json, int maxEntries) { List<SagaFeedEntry> list = ParseSagaFeedEntries(json, maxEntries); if (list.Count == 0) { return false; } _chronicleEntries.Clear(); _chronicleEntries.AddRange(list); ApplySagaChronicleText(BuildSagaPlainText(list)); return true; } private void ApplySagaChronicleText(string text) { if (!string.IsNullOrWhiteSpace(text)) { _sagaChronicleText = text; LogSagaTextLoaded(text); } } private void LogChronicleRefreshFailure(string message) { Plugin.Log.LogWarning((object)("[FehuLanding] Chronicle refresh failed: " + message)); } private void LogSagaTextLoaded(string text) { if (!string.IsNullOrWhiteSpace(text)) { int num = text.Split(new char[1] { '\n' }).Length; string text2 = num + ":" + text.Length; if (!(_lastSagaLogSignature == text2)) { _lastSagaLogSignature = text2; Plugin.Log.LogInfo((object)("[FehuLanding] Saga text loaded: " + num + " lines")); } } } private static string NormalizeChronicleText(string value) { if (string.IsNullOrWhiteSpace(value)) { return value; } List<string> list = new List<string>(); bool flag = false; string[] array = value.Replace("\r\n", "\n").Replace('\r', '\n').Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text = array[i].TrimEnd(Array.Empty<char>()); if (string.IsNullOrWhiteSpace(text)) { if (!flag && list.Count > 0) { list.Add(string.Empty); flag = true; } } else { list.Add(text); flag = false; } } while (list.Count > 0 && string.IsNullOrWhiteSpace(list[list.Count - 1])) { list.RemoveAt(list.Count - 1); } return string.Join("\n", list.ToArray()); } private static string FormatSagaFeed(string json, int maxEntries) { List<SagaFeedEntry> list = ParseSagaFeedEntries(json, maxEntries); if (list.Count == 0) { return null; } return BuildSagaPlainText(list); } private static List<SagaFeedEntry> ParseSagaFeedEntries(string json, int maxEntries) { List<SagaFeedEntry> list = new List<SagaFeedEntry>(); if (string.IsNullOrWhiteSpace(json)) { return list; } foreach (Match item in Regex.Matches(json, "\\{(?<entry>[^{}]*(?:\\{[^{}]*\\}[^{}]*)*)\\}")) { string value = item.Groups["entry"].Value; if (value.Contains("\"title\"")) { SagaFeedEntry sagaFeedEntry = new SagaFeedEntry { TimestampUtc = ReadSagaDate(value, "timestampUtc"), RealmDisplayName = ReadSagaString(value, "realmDisplayName"), Category = ReadSagaString(value, "category"), Title = ReadSagaString(value, "title"), Text = ReadSagaString(value, "text"), Priority = ReadSagaString(value, "priority") }; if (sagaFeedEntry.TimestampUtc == DateTime.MinValue) { sagaFeedEntry.TimestampUtc = ReadSagaDate(value, "timestampUTC"); } if (sagaFeedEntry.TimestampUtc == DateTime.MinValue) { sagaFeedEntry.TimestampUtc = ReadSagaDate(value, "timestamp"); } if (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName)) { sagaFeedEntry.RealmDisplayName = ReadSagaString(value, "server"); } if (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName)) { sagaFeedEntry.RealmDisplayName = ReadSagaString(value, "serverName"); } if (string.IsNullOrWhiteSpace(sagaFeedEntry.Category)) { sagaFeedEntry.Category = ReadSagaString(value, "eventType"); } if (string.IsNullOrWhiteSpace(sagaFeedEntry.Priority)) { sagaFeedEntry.Priority = ReadSagaString(value, "importance"); } sagaFeedEntry.RealmDisplayName = (string.IsNullOrWhiteSpace(sagaFeedEntry.RealmDisplayName) ? "Fehu Realms" : sagaFeedEntry.RealmDisplayName.Trim()); sagaFeedEntry.Category = NormalizeChronicleCategory(sagaFeedEntry.Category); sagaFeedEntry.Priority = NormalizeChroniclePriority(sagaFeedEntry.Priority); sagaFeedEntry.Title = (string.IsNullOrWhiteSpace(sagaFeedEntry.Title) ? "Chronicle" : sagaFeedEntry.Title.Trim()); sagaFeedEntry.Text = (sagaFeedEntry.Text ?? string.Empty).Trim(); list.Add(sagaFeedEntry); } } if (list.Count == 0) { return list; } list.Sort((SagaFeedEntry a, SagaFeedEntry b) => b.TimestampUtc.CompareTo(a.TimestampUtc)); int num = Mathf.Max(1, maxEntries); if (list.Count > num) { list.RemoveRange(num, list.Count - num); } return list; } private static string BuildSagaPlainText(List<SagaFeedEntry> entries) { if (entries == null || entries.Count == 0) { return null; } List<string> list = new List<string>(); for (int i = 0; i < entries.Count; i++) { SagaFeedEntry sagaFeedEntry = entries[i]; list.Add("[" + sagaFeedEntry.RealmDisplayName + "] [" + sagaFeedEntry.Category + "]"); list.Add(sagaFeedEntry.Title); if (!string.IsNullOrWhiteSpace(sagaFeedEntry.Text)) { list.Add(sagaFeedEntry.Text); } list.Add(string.Empty); } return string.Join("\n", list.ToArray()).TrimEnd(Array.Empty<char>()); } private static string NormalizeChronicleCategory(string value) { string text = (value ?? string.Empty).Trim().ToUpperInvariant(); switch (text) { case "CLAN": case "LORE": case "ADMIN": case "EVENT": case "QUEST": case "PLAYER": case "SYSTEM": case "MARKET": case "SERVER": case "WAR": case "TERRITORY": case "KINGDOM": return text; default: return "LORE"; } } private static string NormalizeChroniclePriority(string value) { string text = (value ?? string.Empty).Trim().ToUpperInvariant(); if (text == "CRITICAL" || text == "IMPORTANT") { return text; } return "NORMAL"; } private static string ReadSagaString(string block, string name) { Match match = Regex.Match(block, "\\\"" + Regex.Escape(name) + "\\\"\\s*:\\s*\\\"(?<v>(?:\\\\.|[^\\\"])*)\\\""); if (!match.Success) { return string.Empty; } return match.Groups["v"].Value.Replace("\\n", "\n").Replace("\\\"", "\"").Replace("\\\\", "\\"); } private static DateTime ReadSagaDate(string block, string name) { if (!DateTime.TryParse(ReadSagaString(block, name), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out var result)) { return DateTime.MinValue; } return result.ToUniversalTime(); } private void SetAllMiniVisible(bool visible) { for (int i = 0; i < _miniVisible.Length; i++) { _miniVisible[i] = visible; } } private void BindServerSteamIdIcons(ConfigFile config) { _serverSteamIdIconEntries.Clear(); BindServerSteamIdIcon(config, "10thWorld", defaultValue: false); BindServerSteamIdIcon(config, "Adventure", defaultValue: true); BindServerSteamIdIcon(config, "Immersive", defaultValue: true); BindServerSteamIdIcon(config, "Conquest", defaultValue: false); BindServerSteamIdIcon(config, "Dominion", defaultValue: false); BindServerSteamIdIcon(config, "BuildersHeaven", defaultValue: true); BindServerSteamIdIcon(config, "BalrondRealm", defaultValue: false); BindServerSteamIdIcon(config, "AuroraIII", defaultValue: false); BindServerSteamIdIcon(config, "BlackYmir", defaultValue: true); BindServerSteamIdIcon(config, "TestServer", defaultValue: false); } private void BindServerSteamIdIcon(ConfigFile config, string key, bool defaultValue) { _serverSteamIdIconEntries[key] = config.Bind<bool>("ServerSteamIdIcons", key, defaultValue, "Per-server SteamID icon visibility. true = show steamID.png between Join and Copy IP, false = hide for this server."); } private bool ShouldShowSteamIdIcon(FehuServer server) { if (_enableSteamIdIcons == null || !_enableSteamIdIcons.Value || server == null) { return false; } string text = ServerSteamIdConfigKey(server.name); if (!string.IsNullOrEmpty(text) && _serverSteamIdIconEntries.TryGetValue(text, out var value)) { return value.Value; } return false; } private static string ServerSteamIdConfigKey(string serverName) { string text = Regex.Replace(serverName ?? string.Empty, "[^A-Za-z0-9]", string.Empty).ToLowerInvariant(); switch (text) { case "10thworld": case "fehu10thworld": return "10thWorld"; case "adventure": case "fehuadventure": return "Adventure"; case "immersive": case "fehuimmersive": return "Immersive"; case "conquest": case "fehuconquest": return "Conquest"; case "dominion": case "fehudominion": return "Dominion"; case "buildersheaven": case "fortecabuildersheaven": return "BuildersHeaven"; case "balrondrealm": return "BalrondRealm"; case "auroraiii": case "auroraepisodeiii": return "AuroraIII"; case "blackymir": case "fortecaymir": case "fortecaymireuserver": return "BlackYmir"; case "fehukingdomstest": case "testserver": return "TestServer"; default: return text; } } private void BindMiniPanels(ConfigFile config) { _miniEnabled = new ConfigEntry<bool>[3]; _miniX = new ConfigEntry<int>[3]; _miniY = new ConfigEntry<int>[3]; _miniWidth = new ConfigEntry<int>[3]; _miniHeight = new ConfigEntry<int>[3]; _miniText = new ConfigEntry<string>[3]; _miniIcons = new ConfigEntry<string>[3]; _miniUrl = new ConfigEntry<string>[3]; MiniPanelSettings[] array = new MiniPanelSettings[3] { new MiniPanelSettings { Enabled = true, X = 20, Y = 5, Width = 460, Height = 80, Text = "Forteca", Icons = "1fehu.png,2fehu.png,3fehu.png,4fehu.png", Url = string.Empty }, new MiniPanelSettings { Enabled = true, X = 20, Y = 995, Width = 460, Height = 80, Text = "Press F7 to close all tabs.", Icons = string.Empty, Url = string.Empty }, new MiniPanelSettings { Enabled = true, X = -20, Y = 995, Width = 460, Height = 80, Text = "BLACK VIKING", Icons = string.Empty, Url = string.Empty } }; for (int i = 0; i < array.Length; i++) { string text = "MiniPanel" + (i + 1); _miniEnabled[i] = config.Bind<bool>(text, "Enabled", array[i].Enabled, (ConfigDescription)null); _miniX[i] = config.Bind<int>(text, "X", array[i].X, (ConfigDescription)null); _miniY[i] = config.Bind<int>(text, "Y", array[i].Y, (ConfigDescription)null); _miniWidth[i] = config.Bind<int>(text, "Width", array[i].Width, (ConfigDescription)null); _miniHeight[i] = config.Bind<int>(text, "Height", array[i].Height, (ConfigDescription)null); _miniText[i] = config.Bind<string>(text, "Text", array[i].Text, (ConfigDescription)null); _miniIcons[i] = config.Bind<string>(text, "Icons", array[i].Icons, (ConfigDescription)null); _miniUrl[i] = config.Bind<string>(text, "Url", array[i].Url, (ConfigDescription)null); } } private void BindBottomLegend(ConfigFile config) { _bottomLegendEnabled = config.Bind<bool>("BottomLegend", "EnableBottomLegend", true, (ConfigDescription)null); _leftLegendEnabled = config.Bind<bool>("BottomLegend", "LeftPanelEnabled", true, (ConfigDescription)null); _rightLegendEnabled = config.Bind<bool>("BottomLegend", "RightPanelEnabled", true, (ConfigDescription)null); _bottomLeftLegendX = config.Bind<int>("BottomLegend", "BottomLeftPanelX", 20, (ConfigDescription)null); _bottomLeftLegendY = config.Bind<int>("BottomLegend", "BottomLeftPanelY", -98, (ConfigDescription)null); _bottomRightLegendX = config.Bind<int>("BottomLegend", "BottomRightPanelX", -20, (ConfigDescription)null); _bottomRightLegendY = config.Bind<int>("BottomLegend", "BottomRightPanelY", -98, (ConfigDescription)null); _legendF1Enabled = config.Bind<bool>("BottomLegend", "F1Enabled", true, (ConfigDescription)null); _legendF1Label = config.Bind<string>("BottomLegend", "F1Label", "Configs", (ConfigDescription)null); _legendF3Enabled = config.Bind<bool>("BottomLegend", "F3Enabled", true, (ConfigDescription)null); _legendF3Label = config.Bind<string>("BottomLegend", "F3Label", "Kingdoms", (ConfigDescription)null); _legendF4Enabled = config.Bind<bool>("BottomLegend", "F4Enabled", true, (ConfigDescription)null); _legendF4Label = config.Bind<string>("BottomLegend", "F4Label", "Vault", (ConfigDescription)null); _legendF6Enabled = config.Bind<bool>("BottomLegend", "F6Enabled", true, (ConfigDescription)null); _legendF6Label = config.Bind<string>("BottomLegend", "F6Label", "Rumble", (ConfigDescription)null); _legendF7Enabled = config.Bind<bool>("BottomLegend", "F7Enabled", true, (ConfigDescription)null); _legendF7Label = config.Bind<string>("BottomLegend", "F7Label", "Landing", (ConfigDescription)null); _legendF8Enabled = config.Bind<bool>("BottomLegend", "F8Enabled", true, (ConfigDescription)null); _legendF8Label = config.Bind<string>("BottomLegend", "F8Label", "Arena", (ConfigDescription)null); _legendF9Enabled = config.Bind<bool>("BottomLegend", "F9Enabled", true, (ConfigDescription)null); _legendF9Label = config.Bind<string>("BottomLegend", "F9Label", "Rewards", (ConfigDescription)null); _legendF10Enabled = config.Bind<bool>("BottomLegend", "F10Enabled", true, (ConfigDescription)null); _legendF10Label = config.Bind<string>("BottomLegend", "F10Label", "Factions", (ConfigDescription)null); _steamIdLegendEnabled = config.Bind<bool>("BottomLegend", "SteamIdLegendEnabled", true, (ConfigDescription)null); _steamIdLegendLabel = config.Bind<string>("BottomLegend", "SteamIdLegendLabel", "SteamID Protected Realm", (ConfigDescription)null); } private void BindRealmLegend(ConfigFile config) { _steamIdLegendEnabled = config.Bind<bool>("RealmLegend", "ShowSteamIdLegend", true, (ConfigDescription)null); _joinLegendEnabled = config.Bind<bool>("RealmLegend", "ShowJoinLegend", true, (ConfigDescription)null); _steamIdLegendLabel = config.Bind<string>("RealmLegend", "SteamIdTitle", "SteamID Protected Realm", (ConfigDescription)null); _steamIdLegendText = config.Bind<string>("RealmLegend", "SteamIdText", "Become a Supporter or Contributor\nto gain access.", (ConfigDescription)null); _joinLegendTitle = config.Bind<string>("RealmLegend", "JoinTitle", "Join a Realm", (ConfigDescription)null); _joinLegendText = config.Bind<string>("RealmLegend", "JoinText", "Click the open gate to join.", (ConfigDescription)null); } private void HandlePanelDrag(string id, ref Rect panel, ConfigEntry<int> xEntry, ConfigEntry<int> yEntry, bool rightAnchored, float logicalWidth, float logicalHeight) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Invalid comparison between Unknown and I4 //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Invalid comparison between Unknown and I4 if (IsolationI2StaticRuntime || _enablePanelDragging == null || !_enablePanelDragging.Value || xEntry == null || yEntry == null) { return; } Event current = Event.current; bool flag = current.control || Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); if ((int)current.type == 0 && current.button == 0 && flag && ((Rect)(ref panel)).Contains(current.mousePosition)) { _dragPanelId = id; _dragOffset = current.mousePosition - new Vector2(((Rect)(ref panel)).x, ((Rect)(ref panel)).y); current.Use(); } if (_dragPanelId == id && (int)current.type == 3 && flag) { Vector2 val = current.mousePosition - _dragOffset; ((Rect)(ref panel)).x = Mathf.Clamp(val.x, 0f, Mathf.Max(0f, logicalWidth - ((Rect)(ref panel)).width)); ((Rect)(ref panel)).y = Mathf.Clamp(val.y, 0f, Mathf.Max(0f, logicalHeight - ((Rect)(ref panel)).height)); xEntry.Value = (rightAnchored ? Mathf.RoundToInt(((Rect)(ref panel)).x - (logicalWidth - ((Rect)(ref panel)).width)) : Mathf.RoundToInt(((Rect)(ref panel)).x)); yEntry.Value = Mathf.RoundToInt(((Rect)(ref panel)).y); current.Use(); } if (_dragPanelId == id && ((int)current.type == 1 || !flag)) { ((BaseUnityPlugin)Plugin.Instance).Config.Save(); _dragPanelId = null; if ((int)current.type == 1) { current.Use(); } } } private void DrawTextureSafe(Rect rect, Texture texture, string textureName, ScaleMode scaleMode = (ScaleMode)0, bool alphaBlend = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if ((Object)texture == (Object)null) { LogMissingDrawTextureOnce(textureName); } else { GUI.DrawTexture(rect, texture, scaleMode, alphaBlend); } } private void LogMissingDrawTextureOnce(string textureName) { string text = (string.IsNullOrEmpty(textureName) ? "unknown texture" : textureName); if (_missingDrawTextureLog.Add(text)) { Plugin.Log.LogWarning((object)("[FehuLanding] Missing GUI texture: " + text)); } } private unsafe void DrawSocial(Rect panel, SocialPanelSettings settings) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0043: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Invalid comparison between Unknown and I4 //IL_0218: Unknown result type (might be due to invalid IL or missing references) LoadSocialIconsOnce(); DrawTextureSafe(panel, (Texture)_parchment, "_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 = ((_content != null && _content.socialLinks != null) ? _content.socialLinks : new List<SocialLink>()); Rect val = default(Rect); for (int i = 0; i < list.Count && i < 9; i++) { SocialLink socialLink = list[i]; float num = Mathf.Max(2f, (float)settings.IconSpacing); float num2 = Mathf.Clamp(settings.IconSize, 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); if ((Object)value != (Object)null) { GUI.DrawTexture(val, (Texture)value, (ScaleMode)2, true); string key = "visible:" + socialLink.Icon; string[] array = new string[6] { "[TheFehu] Social icon rendered: ", socialLink.Icon, "\n[TheFehu] Social icon position: ", null, null, null }; Rect val2 = val; array[3] = ((object)(*(Rect*)(&val2))/*cast due to .constrained prefix*/).ToString(); array[4] = "\n[TheFehu] Social icon visible: "; array[5] = socialLink.Icon; LogSocialIcon(key, string.Concat(array)); } if (!string.IsNullOrEmpty(socialLink.Url) && (int)Event.current.type == 1 && Event.current.button == 0 && ((Rect)(ref val)).Contains(Event.current.mousePosition)) { Application.OpenURL(socialLink.Url); Event.current.Use(); } } } private void LoadSocialIconsOnce() { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown if (_socialIconsLoaded) { return; } _socialIconsLoaded = true; string path = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "Assets", "Social"); List<string> obj = ((_content != null && _content.socialLinks != null) ? (from link in _content.socialLinks where !string.IsNullOrWhiteSpace(link.Icon) select link.Icon.Trim()).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList() : new List<string>()); int num = 0; foreach (string item in obj) { string text = Path.Combine(path, item); LogSocialIcon("exists:" + item, "[TheFehu] Social icon file exists: " + item + " " + File.Exists(text).ToString().ToLowerInvariant()); try { Texture2D val = LoadIcon(text); if ((Object)val != (Object)null) { _socialIcons[item] = val; num++; LogSocialIcon("loaded:" + text, "[TheFehu] Social icon loaded: " + item); } else { LogSocialIcon("failed:" + item, "[TheFehu] Social icon failed: " + item); } } catch (Exception ex) { LogSocialIcon("failed:" + item, "[TheFehu] Social icon failed: " + item + " " + ex); } } Plugin.Log.LogInfo((object)("[TheFehu] Social icon count discovered: " + num)); } private void LogSocialIcon(string key, string message) { if (_socialIconLog.Add(key)) { Plugin.Log.LogInfo((object)message); } } private void InitializeShortcutLegendCaches() { _leftShortcutEnabled = new ConfigEntry<bool>[4] { _legendF1Enabled, _legendF3Enabled, _legendF4Enabled, _legendF6Enabled }; _leftShortcutLabels = new ConfigEntry<string>[4] { _legendF1Label, _legendF3Label, _legendF4Label, _legendF6Label }; _rightShortcutEnabled = new ConfigEntry<bool>[4] { _legendF7Enabled, _legendF8Enabled, _legendF9Enabled, _legendF10Enabled }; _rightShortcutLabels = new ConfigEntry<string>[4] { _legendF7Label, _legendF8Label, _legendF9Label, _legendF10Label }; } private Texture2D LoadIcon(string path) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_005b: Expected O, but got Unknown if (CrashIsolationDiagnosticBuild && !Iso(_isoIconsTexturesSprites)) { LogIsolationWarningOnce("IconsTexturesSpritesBypass", "[Isolation] Production icon/texture load bypassed because IsolationEnableIconsTexturesSprites=false"); return null; } if (!File.Exists(path)) { return null; } try { Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, File.ReadAllBytes(path)); if (CrashIsolationDiagnosticBuild) { _isolationTexturesCreated++; } return val; } catch { return null; } } private void DrawMiniPanels(float logicalWidth, float logicalHeight) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (_miniEnabled == null) { return; } Rect panel = default(Rect); for (int i = 0; i < 3; i++) { if (_miniEnabled[i].Value && _miniVisible[i] && (_bottomLegendEnabled == null || !_bottomLegendEnabled.Value || i <= 0)) { MiniPanelSettings miniPanelSettings = new MiniPanelSettings { Enabled = true, X = _miniX[i].Value, Y = _miniY[i].Value, Width = _miniWidth[i].Value, Height = _miniHeight[i].Value, Text = _miniText[i].Value, Icons = _miniIcons[i].Value, Url = _miniUrl[i].Value }; bool flag = miniPanelSettings.X < 0; ((Rect)(ref panel))..ctor(flag ? (logicalWidth - (float)miniPanelSettings.Width + (float)miniPanelSettings.X) : ((float)miniPanelSettings.X), (float)miniPanelSettings.Y, (float)miniPanelSettings.Width, (float)miniPanelSettings.Height); HandlePanelDrag("MiniPanel" + (i + 1), ref panel, _miniX[i], _miniY[i], flag, logicalWidth, logicalHeight); DrawMiniPanel("MiniPanel" + (i + 1), panel, miniPanelSettings, ref _miniVisible[i]); } } } private string[] GetMiniIcons(MiniPanelSettings mini) { string text = ((mini != null) ? (mini.Icons ?? string.Empty) : string.Empty); if (_miniIconListCache.TryGetValue(text, out var value)) { return value; } if (string.IsNullOrWhiteSpace(text)) { _miniIconListCache[text] = new string[0]; return _miniIconListCache[text]; } List<string> list = new List<string>(4); int num = 0; for (int i = 0; i <= text.Length; i++) { if (i != text.Length && text[i] != ',') { continue; } if (i > num) { string text2 = text.Substring(num, i - num).Trim(); if (text2.Length > 0) { list.Add(text2); } } num = i + 1; } string[] array = list.ToArray(); _miniIconListCache[text] = array; return array; } private void DrawMiniPanel(string id, Rect panel, MiniPanelSettings mini, ref bool visible) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Invalid comparison between Unknown and I4 //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) DrawTextureSafe(panel, (Texture)_parchment, "_parchment", (ScaleMode)0); if (GUI.Button(new Rect(((Rect)(ref panel)).xMax - 28f, ((Rect)(ref panel)).y + 4f, 20f, 20f), "x", _buttonStyle)) { visible = false; Plugin.Log.LogInfo((object)("[TheFehu] Close panel clicked: " + id)); return; } float num = ((Rect)(ref panel)).x + 12f; string[] miniIcons = GetMiniIcons(mini); if (miniIcons.Length != 0) { float num2 = Mathf.Min(46f, ((Rect)(ref panel)).height - 22f); int num3 = Mathf.Min(4, miniIcons.Length); for (int i = 0; i < num3; i++) { Texture2D val = LoadAssetIcon(miniIcons[i]); if ((Object)val != (Object)null) { GUI.DrawTexture(new Rect(num, ((Rect)(ref panel)).y + (((Rect)(ref panel)).height - num2) * 0.5f, num2, num2), (Texture)val, (ScaleMode)2, true); } num += num2 + 8f; } } else { Texture2D val2 = LoadAssetIcon(mini.Icon); if ((Object)val2 != (Object)null) { float num4 = Mathf.Min(48f, ((Rect)(ref panel)).height - 18f); GUI.DrawTexture(new Rect(num, ((Rect)(ref panel)).y + (((Rect)(ref panel)).height - num4) * 0.5f, num4, num4), (Texture)val2, (ScaleMode)2, true); num += num4 + 10f; } } if (!string.IsNullOrEmpty(mini.Text)) { GUI.Label(new Rect(num, ((Rect)(ref panel)).y + 12f, ((Rect)(ref panel)).xMax - num - 28f, ((Rect)(ref panel)).height - 24f), mini.Text, _bodyStyle); } if (!string.IsNullOrEmpty(mini.Url) && (int)Event.current.type == 1 && Event.current.button == 0 && ((Rect)(ref panel)).Contains(Event.current.mousePosition)) { Application.OpenURL(mini.Url); Event.current.Use(); } } private void DrawBottomLegend(float logicalWidth, float logicalHeight) { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (_bottomLegendEnabled != null && _bottomLegendEnabled.Value) { float num = Math.Max(360f, (_newsWidth != null) ? ((float)_newsWidth.Value) : 460f); float num2 = Math.Max(70f, (_socialHeight != null) ? ((float)_socialHeight.Value) : 80f); int num3 = ((_bottomLeftLegendX != null) ? _bottomLeftLegendX.Value : 20); int num4 = ((_bottomLeftLegendY != null) ? _bottomLeftLegendY.Value : (-98)); int num5 = ((_bottomRightLegendX != null) ? _bottomRightLegendX.Value : (-20)); int num6 = ((_bottomRightLegendY != null) ? _bottomRightLegendY.Value : (-98)); Rect panel = default(Rect); ((Rect)(ref panel))..ctor((float)num3, (num4 < 0) ? (logicalHeight + (float)num4) : ((float)num4), num, num2); Rect panel2 = default(Rect); ((Rect)(ref panel2))..ctor(logicalWidth - num + (float)num5, (num6 < 0) ? (logicalHeight + (float)num6) : ((float)num6), num, num2); HandlePanelDrag("BottomLegendLeft", ref panel, _bottomLeftLegendX, _bottomLeftLegendY, rightAnchored: false, logicalWidth, logicalHeight); HandlePanelDrag("BottomLegendRight", ref panel2, _bottomRightLegendX, _bottomRightLegendY, rightAnchored: true, logicalWidth, logicalHeight); if ((_leftLegendEnabled == null || _leftLegendEnabled.Value) && _bottomLeftLegendVisible) { DrawShortcutLegendPanel(panel, LeftShortcutIcons, LeftShortcutDefaults, 4, 1, leftPanel: true); DrawBottomLegendCloseButton(panel, leftPanel: true); DrawThemeSelector(panel); } else if (!_bottomLeftLegendVisible) { _themeSelectorVisible = false; } if ((_rightLegendEnabled == null || _rightLegendEnabled.Value) && _bottomRightLegendVisible) { DrawShortcutLegendPanel(panel2, RightShortcutIcons, RightShortcutDefaults, 4, 2, leftPanel: false); DrawBottomLegendCloseButton(panel2, leftPanel: false); } } } private void DrawBottomLegendCloseButton(Rect panel, bool leftPanel) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) Rect val = new Rect(((Rect)(ref panel)).xMax - 24f, ((Rect)(ref panel)).y + 4f, 20f, 20f); int fontSize = _buttonStyle.fontSize; _buttonStyle.fontSize = 12; if (GUI.Button(val, "X", _buttonStyle)) { if (leftPanel) { _bottomLeftLegendVisible = false; _themeSelectorVisible = false; } else { _bottomRightLegendVisible = false; } } _buttonStyle.fontSize = fontSize; } private void DrawShortcutLegendPanel(Rect panel, string[] icons, string[] labels, int columns, int rows, bool leftPanel) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Invalid comparison between Unknown and I4 //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Invalid comparison between Unknown and I4 //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) DrawTextureSafe(panel, (Texture)(((Object)_bottomPanel != (Object)null) ? _bottomPanel : _parchment), "_bottomPanel/_parchment", (ScaleMode)0); int fontSize = _bodyStyle.fontSize; bool wordWrap = _bodyStyle.wordWrap; TextAnchor alignment = _bodyStyle.alignment; _bodyStyle.fontSize = ((rows > 1) ? Mathf.Max(9, fontSize - 5) : Mathf.Max(10, fontSize - 4)); _bodyStyle.wordWrap = false; _bodyStyle.alignment = (TextAnchor)4; float num = (leftPanel ? 14f : 10f); float num2 = ((rows > 1) ? 5f : 7f); float num3 = (leftPanel ? 10f : 6f); float num4 = ((rows > 1) ? 2f : 0f); float num5 = (((Rect)(ref panel)).width - num * 2f - num3 * (float)(columns - 1)) / (float)columns; float num6 = (((Rect)(ref panel)).height - num2 * 2f - num4 * (float)(rows - 1)) / (float)rows; float num7 = ((rows > 1) ? Mathf.Min(22f, num6 - 10f) : Mathf.Min(44f, num6 - 8f)); num7 = Mathf.Max(14f, num7); Event current = Event.current; Rect val = default(Rect); for (int i = 0; i < labels.Length && i < icons.Length && i < rows * columns; i++) { int num8 = i % columns; int num9 = i / columns; ((Rect)(ref val))..ctor(((Rect)(ref panel)).x + num + (float)num8 * (num5 + num3), ((Rect)(ref panel)).y + num2 + (float)num9 * (num6 + num4), num5, num6); bool num10 = ((Rect)(ref val)).Contains(current.mousePosition); if (num10 && ((int)current.type == 7 || (int)current.type == 8)) { GUI.color = new Color(1f, 0.74f, 0.28f, 0.18f); DrawTextureSafe(val, (Texture)_buttonStyle.hover.background, "_buttonStyle.hover.background", (ScaleMode)0); GUI.color = Color.white; } if (num10 && (int)current.type == 0 && current.button == 0) { HandleShortcutClick(leftPanel, i); current.Use(); } if (leftPanel) { DrawLeftLandingControlCell(val, labels[i], icons[i]); } else { DrawRightShortcutCell(val, labels[i], icons[i]); } } _bodyStyle.fontSize = fontSize; _bodyStyle.wordWrap = wordWrap; _bodyStyle.alignment = alignment; } private void HandleShortcutClick(bool leftPanel, int index) { if (leftPanel) { switch (index) { case 0: OpenThemeWindow(); break; case 3: ToggleLandingTabs(); break; } } } private void ToggleLandingTabs() { if (_hiddenForSession) { RestoreLandingTabs(); } else { CloseAllLandingTabs(); } } private void RestoreLandingTabs() { _hiddenForSession = false; _topLeftVisible = true; _bottomLeftVisible = true; _topRightVisible = true; _bottomRightVisible = true; _socialVisible = true; _bottomLeftLegendVisible = true; _bottomRightLegendVisible = true; S