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 Hearthforge v1.0.5
plugins/Hearthforge.dll
Decompiled 9 hours 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.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Hearthforge.Core; using Hearthforge.Modules; using Hearthforge.Modules.Hud; using Hearthforge.UI; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Hearthforge")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.158.0")] [assembly: AssemblyInformationalVersion("1.1.158+0f16abd-dirty.202610221603")] [assembly: AssemblyProduct("Hearthforge")] [assembly: AssemblyTitle("Hearthforge")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially created with the assistance of Generative AI (code and documentation), reviewed and tested by the author.")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Grok Bot")] [assembly: AssemblyVersion("1.1.158.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 Hearthforge { [BepInPlugin("spencer.hearthforge", "Hearthforge", "1.1.159")] public class Plugin : BaseUnityPlugin { public const string Guid = "spencer.hearthforge"; public const string ModName = "Hearthforge"; public const string Version = "1.1.159"; internal static ManualLogSource Log; private Harmony coreHarmony; public static Plugin Instance { get; private set; } public ModuleManager Modules { get; private set; } private void Awake() { //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; LogBuild(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; Options.Init(((BaseUnityPlugin)this).Config); SettingsPanel.BindOptions(); ConfigSync.BindOptions(); Modules = new ModuleManager(((BaseUnityPlugin)this).Logger); Modules.Register<HaulingSkillModule>(); Modules.Register<SwimTweaksModule>(); Modules.Register<SkipIntroModule>(); Modules.Register<RestingModule>(); Modules.Register<LootingModule>(); Modules.Register<AxeComboModule>(); Modules.Register<TeleportModule>(); Modules.Register<PlantingModule>(); Modules.Register<ExplorationModule>(); Modules.Register<HearthModule>(); Modules.Register<BackpackModule>(); Modules.Register<QuartermasterModule>(); Modules.Register<SocialModule>(); Modules.Register<DeathPenaltyModule>(); Modules.Register<TraderStallModule>(); Modules.Register<DvergrBuildModule>(); Modules.Register<MapStyleModule>(); Modules.Register<BushPlantingModule>(); Modules.Register<RuneforgeModule>(); Modules.Register<TabTargetModule>(); Modules.Register<PlantEverythingModule>(); Modules.Register<AchievementsModule>(); Modules.Register<DevCommandsModule>(); Modules.Register<ZoneResetModule>(); Modules.Register<WardGuardModule>(); Modules.Register<WaterModule>(); Modules.Register<EquipmentPanelModule>(); Modules.Register<InfiniteFuelModule>(); Modules.Register<CaveFogModule>(); Modules.Register<CameraModule>(); Modules.Register<MeadowsAnywhereModule>(); Modules.Register<WispColumnModule>(); Modules.Register<BulkLoadModule>(); Modules.Register<StorageModule>(); Modules.Register<ApiaryModule>(); Modules.Register<CoinPurseModule>(); Modules.Register<GraveyardModule>(); Modules.Register<SmelteryModule>(); Modules.Register<ProspectorModule>(); Modules.Register<OfflineProgressModule>(); Modules.Register<FermenterModule>(); Modules.Register<YggdrasilRootModule>(); Modules.Register<ShipStyleModule>(); Modules.Register<WishboneModule>(); Modules.Register<GildedUIModule>(); Modules.Register<HomesteadModule>(); Modules.Register<SignStyleModule>(); Modules.Register<WellFedModule>(); Modules.Register<BossStonesModule>(); Modules.Register<AdminAreaCopyModule>(); Modules.Register<TerrainToolsModule>(); Modules.Register<GraphicsModule>(); Modules.Register<StationScaleModule>(); Modules.Register<ShipSalvageModule>(); Modules.Register<SailingModule>(); Modules.Register<SlopeAssistModule>(); Modules.Register<BuildInteractModule>(); Modules.Register<TrailsModule>(); Modules.Register<LongshipHarborModule>(); Modules.Register<TamerModule>(); Modules.Register<DyeModule>(); Modules.Register<HudModule>(); Modules.Register<SeedPreviewModule>(); Modules.Register<TerrainEditCapModule>(); Modules.Register<EquippedHighlightModule>(); Modules.Register<DayNightModule>(); Modules.Register<ArmorStandSwapModule>(); Modules.Register<WorldRenewModule>(); Modules.InitAll(); coreHarmony = new Harmony("spencer.hearthforge.core"); Type[] array = new Type[15] { typeof(ConfigSync.Hooks), typeof(Staff.Hooks), typeof(InputBlock), typeof(StartupGuard), typeof(PieceKit.Hooks), typeof(UnlockMsgGuard), typeof(RecipeGuard), typeof(ContainerRpcFix), typeof(DevCommands), typeof(LegacyCleanup), typeof(BagGuard), typeof(KilnGuard), typeof(PieceTags.Patches), typeof(OfflineProgressModule.Patches), typeof(VoxheimSafety.Patches) }; foreach (Type type in array) { try { coreHarmony.CreateClassProcessor(type).Patch(); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Core patch {type.Name} failed and was skipped: {arg}"); } } InstanceReport.On = Options.Bind("Debug", "InstanceReport", def: false, "Every minute, log networked instance counts (top prefabs and all Hearthforge objects)", synced: false); ((Component)this).gameObject.AddComponent<InstanceReport>(); FxSweeper.On = Options.Bind("Debug", "FxSweeper", def: false, "FX Sweeper log: also log vanilla and other mods' odd-looking effects (debug only). Broken Hearthforge effects are always switched off. Console: hf_fx", synced: false); ModOption<bool> modOption = Options.Bind("Debug", "DebugLogsOff1161", def: false, "Internal: debug logs default migrated to off", synced: false); if (!modOption.Value) { FxSweeper.On.Value = false; InstanceReport.On.Value = false; modOption.Value = true; } ((Component)this).gameObject.AddComponent<FxSweeper>(); PerfMonitor.Overlay = Options.Bind("Debug", "PerfOverlay", def: false, "Perf overlay: per-module ms/frame, calls and KB allocated per frame (only measured while on; off = zero cost). Console: hf_perf [seconds] dumps to the log", synced: false); PerfMonitor.Profiler = Options.Bind("Debug", "Profiler", def: false, "Profiler: once a minute, log the 10 most expensive Hearthforge patches and updates of that minute (times every Hearthforge method only while on; off = zero cost)", synced: false); ((Component)this).gameObject.AddComponent<PerfMonitor>(); try { ((Component)this).gameObject.AddComponent<SettingsPanel>(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Settings panel failed: " + ex)); } PurgeOrphanedConfig(); ((BaseUnityPlugin)this).Logger.LogMessage((object)string.Format("===== {0} {1} loaded ({2} modules, {3} options) =====", "Hearthforge", "1.1.159", Modules.List.Count, Options.All.Count)); try { HashSet<string> vis = new HashSet<string> { "Graphics", "CaveFog", "Camera", "SwimTweaks", "WispColumn" }; List<string> list = (from o in Options.All where vis.Contains(o.Module) && !object.Equals(o.Boxed, o.DefaultBoxed) select $"{o.Module}.{o.Key}={o.Boxed}").ToList(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Visuals] non-default settings: " + ((list.Count == 0) ? "none (all vanilla defaults)" : string.Join(", ", list)))); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Visuals] settings dump failed: " + ex2.Message)); } } private void PurgeOrphanedConfig() { try { if (!(AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(((BaseUnityPlugin)this).Config) is Dictionary<ConfigDefinition, string> { Count: not 0 } dictionary)) { return; } List<ConfigDefinition> list = dictionary.Keys.Where((ConfigDefinition d) => !d.Section.StartsWith("Knarr", StringComparison.Ordinal)).ToList(); if (list.Count == 0) { return; } foreach (ConfigDefinition item in list) { dictionary.Remove(item); } int count = list.Count; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Removed {count} obsolete setting(s) from the config file."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Config cleanup skipped: " + ex.Message)); } } private void LogBuild() { Assembly assembly = typeof(Plugin).Assembly; AssemblyInformationalVersionAttribute assemblyInformationalVersionAttribute = (AssemblyInformationalVersionAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyInformationalVersionAttribute)); string location = assembly.Location; string text = (File.Exists(location) ? File.GetLastWriteTime(location).ToString("yyyy-MM-dd HH:mm:ss") : "?"); ((BaseUnityPlugin)this).Logger.LogMessage((object)("Hearthforge build " + (assemblyInformationalVersionAttribute?.InformationalVersion ?? "1.1.159") + " | " + location + " | file time " + text)); try { string[] files = Directory.GetFiles(Paths.PluginPath, "Hearthforge*.dll", SearchOption.AllDirectories); foreach (string text2 in files) { if (!string.Equals(Path.GetFullPath(text2), Path.GetFullPath(location), StringComparison.OrdinalIgnoreCase)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Another Hearthforge DLL is installed and may be loaded instead of this one: " + text2)); } } } catch { } } private void OnDestroy() { Harmony obj = coreHarmony; if (obj != null) { obj.UnpatchSelf(); } Modules?.DisableAll(); } } } namespace Hearthforge.UI { public static class ConfirmDialog { private class Keys : MonoBehaviour { private void Update() { if (Widgets.KeyDown((KeyCode)27)) { SettingsPanel.SwallowEscapeFrame = Time.frameCount; Close(ok: false); } else if ((Object)(object)Player.m_localPlayer == (Object)null) { Close(ok: false); } } } private static GameObject root; private static TextMeshProUGUI title; private static TextMeshProUGUI text; private static TextMeshProUGUI yesLabel; private static Action yes; public static bool IsOpen { get { if ((Object)(object)root != (Object)null) { return root.activeSelf; } return false; } } public static void Ask(string heading, string body, string yesText, Action onYes) { if ((Object)(object)root == (Object)null) { Build(); } yes = onYes; ((TMP_Text)title).text = heading; ((TMP_Text)text).text = body; ((TMP_Text)yesLabel).text = yesText; root.SetActive(true); root.transform.SetAsLastSibling(); UiFocus.Grab(); } private static void Close(bool ok) { if ((Object)(object)root != (Object)null) { root.SetActive(false); } Action action = yes; yes = null; if (ok) { try { action?.Invoke(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[UI] confirm action failed: " + ex.Message)); } } } private static void Build() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_008a: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) root = new GameObject("HF_Confirm", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)root); Canvas component = root.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 30025; CanvasScaler component2 = root.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.matchWidthOrHeight = 0.5f; HfCanvas.Register(component2); RectTransform val = Theme.Rect("Window", root.transform); Theme.Place(val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(600f, 290f)); Gilded.WindowBg(val); RectTransform obj = Theme.Rect("Title", (Transform)(object)val, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(10f, -58f), new Vector2(-10f, -10f)); Theme.TitleBarImg((Component)(object)obj); ((Component)obj).gameObject.AddComponent<Draggable>().Target = val; title = Theme.Label((Transform)(object)obj, "", 24f, Theme.Gold, (TextAlignmentOptions)513, header: true); ((TMP_Text)title).rectTransform.offsetMin = new Vector2(16f, 0f); text = Theme.Label((Transform)(object)Theme.Rect("Body", (Transform)(object)val, Vector2.zero, Vector2.one, new Vector2(24f, 76f), new Vector2(-24f, -68f)), "", 17f, Theme.Text, (TextAlignmentOptions)514); ((TMP_Text)text).textWrappingMode = (TextWrappingModes)1; RectTransform obj2 = Theme.Rect("Yes", (Transform)(object)val); Theme.Place(obj2, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-95f, 20f), new Vector2(170f, 42f)); yesLabel = ((Component)Widgets.Button((Transform)(object)obj2, "Yes", delegate { Close(ok: true); }, 17f)).GetComponentInChildren<TextMeshProUGUI>(); RectTransform obj3 = Theme.Rect("No", (Transform)(object)val); Theme.Place(obj3, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(95f, 20f), new Vector2(170f, 42f)); Widgets.Button((Transform)(object)obj3, "Cancel", delegate { Close(ok: false); }, 17f); root.AddComponent<Keys>(); root.SetActive(false); } } public static class F7Catalog { public struct Spot { public string Page; public string Section; public bool Advanced; } public const string HUD = "HUD"; public const string Frames = "Frames"; public const string Other = "Other Mods"; public const string Misc = "Miscellaneous"; public const string Admin = "Admin"; public const string AdminSettings = "AdminSettings"; public const string StaffPage = "Staff"; public static readonly string[] Categories; private static readonly Dictionary<string, string> cat; private static readonly Dictionary<string, string> parent; private static readonly Dictionary<string, string> section; private static readonly Dictionary<string, string> keySection; private static readonly Dictionary<string, string> toFrames; private static readonly HashSet<string> hudFrameKeys; private static readonly Dictionary<string, string> subtitle; private static readonly HashSet<string> advanced; private static readonly Regex advKey; private static readonly HashSet<(string, string)> internalKeys; private static int adminFrame; private static bool adminView; public static bool AdminView { get { int frameCount = Time.frameCount; if (frameCount != adminFrame) { adminFrame = frameCount; adminView = Staff.LocalIsAdmin(); } return adminView; } } public static bool StaffView { get { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.IsSinglePlayer) { if (!AdminView) { return Staff.Me != Staff.Role.Player; } return true; } return false; } } public static IEnumerable<IOption> Visible => Options.All.Where((IOption o) => !Internal(o)); private static void C(string c, params string[] pages) { foreach (string key in pages) { cat[key] = c; } } static F7Catalog() { Categories = new string[13] { "Performance", "Graphics", "HUD", "Frames", "World & Travel", "Building & Base", "Farming & Production", "Inventory & Storage", "Combat & Gear", "Social", "Server & Debug", "Admin", "Miscellaneous" }; cat = new Dictionary<string, string>(); parent = new Dictionary<string, string> { { "Hearth", "Teleport" }, { "GreenhandBushes", "Planting" }, { "PlantEverything", "Planting" }, { "TerrainEditCap", "TerrainTools" }, { "UI", "GildedUI" }, { "Debug", "Server" }, { "WarbandHUD", "HUD" }, { "EquippedHighlight", "HUD" }, { "TabTarget", "HUD" } }; section = new Dictionary<string, string> { { "Hearth", "Hearthstone" }, { "GreenhandBushes", "Bushes" }, { "PlantEverything", "Wild Plants" }, { "TerrainEditCap", "Terrain Edit Limit" }, { "UI", "Settings Window (F7)" }, { "Debug", "Debugging" }, { "WarbandHUD", "General" }, { "EquippedHighlight", "Equipped Glow" }, { "TabTarget", "Targeting" } }; keySection = new Dictionary<string, string>(); toFrames = new Dictionary<string, string> { { "WarbandHUD.UnlockFramesKey", "Unlock Frames" }, { "WarbandHUD.HideFramesWithInventory", "Unlock Frames" }, { "WarbandHUD.HideVanillaFrames", "Unlock Frames" }, { "EquipmentPanel.CharacterPanelScale", "Character Panel" }, { "EquipmentPanel.ShowStats", "Character Panel" }, { "EquipmentPanel.PanelOffsetX", "Character Panel" }, { "EquipmentPanel.PanelOffsetY", "Character Panel" }, { "UI.PanelX", "Settings Window (F7)" }, { "UI.PanelY", "Settings Window (F7)" }, { "UI.PanelScale", "Settings Window (F7)" }, { "HUD Bags.BagOffsetX", "Bag, Chest & Crafting Windows" }, { "HUD Bags.BagOffsetY", "Bag, Chest & Crafting Windows" }, { "HUD Bags.ChestOffsetX", "Bag, Chest & Crafting Windows" }, { "HUD Bags.ChestOffsetY", "Bag, Chest & Crafting Windows" }, { "HUD Bags.CraftOffsetX", "Bag, Chest & Crafting Windows" }, { "HUD Bags.CraftOffsetY", "Bag, Chest & Crafting Windows" }, { "HUD Bags.ResetWindowPositions", "Bag, Chest & Crafting Windows" } }; hudFrameKeys = new HashSet<string> { "Scale", "PosX", "PosY" }; subtitle = new Dictionary<string, string> { { "HUD", "Every HUD piece in one place" }, { "Frames", "Positions and sizes of every frame and window" }, { "Teleport", "Portals, map travel, Hearthstone" }, { "Exploration", "Exploring and map fog" }, { "MapStyle", "Map look" }, { "Sailing", "Sailing and ships" }, { "LongshipHarbor", "Dock and store ships" }, { "SwimTweaks", "Swimming" }, { "Trails", "Paths you walk often" }, { "BossStones", "Boss altars" }, { "Wishbone", "Quieter Wishbone" }, { "AreaReset", "Reset world areas" }, { "SeedPreview", "World seed preview" }, { "MeadowsAnywhere", "Meadows plants anywhere" }, { "Water", "Rivers and water" }, { "WispColumn", "Wisp beacon in the sky" }, { "SkipIntro", "Faster start-up" }, { "HomesteadMove", "Move a whole base" }, { "DvergrBuild", "Dvergr building pieces" }, { "SlopeAssist", "Building on slopes" }, { "BuildInteract", "Use E while building" }, { "TerrainTools", "Hoe, pickaxe, terrain" }, { "SignStyle", "Sign text styling" }, { "WardGuard", "Keep mobs out, ward radius" }, { "YggdrasilRoot", "Sap roots (full and mini)" }, { "TraderStalls", "Place traders at home" }, { "Shipwright", "Ship looks" }, { "ShipSalvage", "Take ships apart with the hammer" }, { "StationScale", "Smaller smelting stations" }, { "Resting", "Rested buff, comfort" }, { "AxeCombo", "Chopping trees" }, { "Planting", "Crops, bushes, wild plants" }, { "Apiary", "Beehives and harvest" }, { "Brewmaster", "Fermenters, honey, queue" }, { "Smeltery", "Smelters and kilns" }, { "InfiniteFuel", "Fires that never go out" }, { "Tamer", "Taming and breeding" }, { "Prospector", "Mining" }, { "OfflineProgress", "Work while you're away" }, { "DeathPenalty", "Death penalty" }, { "Graveyard", "Tombstones" }, { "WellFed", "Food" }, { "HaulingSkill", "Carry weight skill" }, { "Runeforge", "Weapon imbues" }, { "Dye", "Dye your gear" }, { "Achievements", "Achievements" }, { "EquipmentPanel", "Character gear panel" }, { "Storage", "Quick Stack, Ward Organize" }, { "Quartermaster", "Craft from chests, Never Pull" }, { "LootFilter", "Auto-pickup, Loot Filter" }, { "Backpacks", "Backpack" }, { "CoinPurse", "Coins" }, { "BulkLoad", "Load stations in bulk" }, { "Social", "Party and friends" }, { "GildedUI", "Look of the UI, F7 window" }, { "Camera", "Camera" }, { "Graphics", "Haze, fog, shadows, clarity, stars, rain, sun shafts, ocean" }, { "CaveFog", "Cave fog" }, { "Server", "Server sync, debugging" }, { "AdminSettings", "Every server-synced setting (admins only)" }, { "Staff", "Players, roles, kick and ban" }, { "DevCommands", "Admin commands" }, { "AdminAreaCopy", "Copy areas (admin)" } }; advanced = new HashSet<string> { "Server.SyncOtherMods", "Server.VersionCheck", "Graphics.ReflectionResolution", "Graphics.ReflectionSmooth", "Graphics.ReflectionHdr", "Graphics.WaterFoam", "Graphics.Caustics", "Graphics.CausticsStrength" }; advKey = new Regex("(Debug|Verbose|Logs?$|Logging|Interval|Tick|Budget|Cache|Throttle|Timeout|Migrat|^Load[A-Z]|[A-Za-z][0-9]{3,4}$)", RegexOptions.Compiled); internalKeys = new HashSet<(string, string)>(); adminFrame = -1; C("Performance", "CaveFog"); C("Graphics", "Graphics", "WispColumn", "Camera", "GildedUI"); C("HUD", "HUD"); C("Frames", "Frames"); C("World & Travel", "Teleport", "SwimTweaks", "Exploration", "MeadowsAnywhere", "SkipIntro", "MapStyle", "Sailing", "LongshipHarbor", "Trails", "BossStones", "Wishbone", "AreaReset", "SeedPreview", "Water"); C("Building & Base", "WardGuard", "BuildInteract", "Resting", "YggdrasilRoot", "AxeCombo", "HomesteadMove", "DvergrBuild", "SlopeAssist", "TerrainTools", "SignStyle", "TraderStalls", "Shipwright", "StationScale", "ShipSalvage"); C("Farming & Production", "Apiary", "Planting", "Smeltery", "Prospector", "Brewmaster", "OfflineProgress", "InfiniteFuel", "Tamer"); C("Inventory & Storage", "Storage", "Quartermaster", "Backpacks", "LootFilter", "BulkLoad", "CoinPurse"); C("Combat & Gear", "EquipmentPanel", "Runeforge", "Dye", "DeathPenalty", "Graveyard", "WellFed", "HaulingSkill"); C("Social", "Social", "Achievements"); C("Server & Debug", "Server", "DevCommands", "AdminAreaCopy"); C("Admin", "Staff", "AdminSettings"); } public static bool IsHudFrame(string m) { return m?.StartsWith("HUD ") ?? false; } public static bool IsVanillaFrame(string m) { return m?.StartsWith("Frames ") ?? false; } public static bool Collapsible(string page) { if (!(page == "HUD") && !(page == "Frames")) { return page == "AdminSettings"; } return true; } public static Spot Of(IOption o) { if (o.ServerSynced && !(o is ForeignOption) && !o.Module.StartsWith("ext:")) { Spot spot = OfBase(o); string text = Title(spot.Page); return new Spot { Page = "AdminSettings", Section = ((spot.Section != null && spot.Section != text) ? (text + " › " + spot.Section) : text) }; } return OfBase(o); } private static Spot OfBase(IOption o) { string module = o.Module; if (module.StartsWith("ext:")) { return new Spot { Page = module }; } if (toFrames.TryGetValue(module + "." + o.Key, out var value)) { return new Spot { Page = "Frames", Section = value }; } if (IsVanillaFrame(module)) { return new Spot { Page = "Frames", Section = module.Substring(7) + " (game window)" }; } if (IsHudFrame(module)) { if (!hudFrameKeys.Contains(o.Key)) { return new Spot { Page = "HUD", Section = module.Substring(4) }; } return new Spot { Page = "Frames", Section = module.Substring(4) }; } string text = Parent(module); string value2; string text2 = ((text == module) ? null : (section.TryGetValue(module, out value2) ? value2 : Options.Display(module))); if (keySection.TryGetValue(module + "." + o.Key, out var value3)) { text2 = value3; } bool flag = !Collapsible(text) && o.Key != "Enabled" && (module == "Debug" || advanced.Contains(module + "." + o.Key) || advKey.IsMatch(o.Key)); return new Spot { Page = text, Section = text2, Advanced = flag }; } public static string Parent(string m) { if (m == null || !parent.TryGetValue(m, out var value)) { if (!IsHudFrame(m)) { if (!IsVanillaFrame(m)) { return m; } return "Frames"; } return "HUD"; } return value; } public static string PageOf(string module) { if (module != null) { if (!module.StartsWith("ext:") && !(module == "HUD") && !(module == "Frames")) { return Parent(module); } return module; } return null; } public static string Category(string page) { if (page != null) { if (!page.StartsWith("ext:")) { if (!cat.TryGetValue(page, out var value)) { return "Miscellaneous"; } return value; } return "Other Mods"; } return "Miscellaneous"; } public static string Subtitle(string page) { if (page == null || !subtitle.TryGetValue(page, out var value)) { return ""; } return value; } public static string Title(string page) { return page switch { "AdminSettings" => "Server Settings", "Frames" => "Frames", "HUD" => "HUD", _ => Options.Display(page), }; } public static bool IsInternal(IOption o) { if (o.Description == null || !o.Description.StartsWith("Internal:")) { if (!(o is ForeignOption)) { if (!internalKeys.Contains((o.Module, o.Key))) { if (o.ServerSynced) { return !AdminView; } return false; } return true; } return false; } return true; } private static bool Internal(IOption o) { return IsInternal(o); } public static List<(string cat, List<string> pages)> Group() { List<string> list = new List<string>(); if (StaffView) { list.Add("Staff"); } foreach (IOption item in Visible) { string page = Of(item).Page; if (!list.Contains(page)) { list.Add(page); } } List<(string, List<string>)> list2 = new List<(string, List<string>)>(); string[] categories = Categories; foreach (string c in categories) { List<string> list3 = list.Where((string p) => Category(p) == c).ToList(); if (list3.Count > 0) { list2.Add((c, list3)); } } return list2; } public static List<(string section, List<IOption> opts)> Sections(string page) { List<(string, List<IOption>)> list = new List<(string, List<IOption>)>(); List<IOption> list2 = new List<IOption>(); foreach (IOption item3 in Visible) { Spot s = Of(item3); if (s.Page != page) { continue; } if (s.Section == null) { list2.Add(item3); continue; } int num = list.FindIndex(((string section, List<IOption> opts) x) => x.section == s.Section); if (num < 0) { list.Add((s.Section, new List<IOption> { item3 })); } else { list[num].Item2.Add(item3); } } if (page == "HUD") { int num2 = list.FindIndex(((string section, List<IOption> opts) x) => x.section == "General"); if (num2 > 0) { (string, List<IOption>) item = list[num2]; list.RemoveAt(num2); list.Insert(0, item); } } if (page == "Frames") { int num3 = list.FindIndex(((string section, List<IOption> opts) x) => x.section == "Unlock Frames"); if (num3 > 0) { (string, List<IOption>) item2 = list[num3]; list.RemoveAt(num3); list.Insert(0, item2); } } if (list2.Count > 0) { list.Insert(0, (null, list2)); } return list.Select<(string, List<IOption>), (string, List<IOption>)>(((string section, List<IOption> opts) r) => (section: r.section, StableEnabledFirst(r.opts))).ToList(); } private static List<IOption> StableEnabledFirst(List<IOption> l) { return l.Where((IOption o) => o.Key == "Enabled").Concat(l.Where((IOption o) => o.Key != "Enabled")).ToList(); } } public interface IChoices { object[] Choices { get; } } public interface IChoiceLabels { string ChoiceLabel(object v); } public sealed class ForeignOption : IOption, IChoices, IChoiceLabels { public readonly ForeignMod Mod; private readonly ConfigEntryBase e; internal readonly string HayKey; private readonly object[] fixedChoices; private static Dictionary<string, string> envBiomes; private static List<string> envCache; private static EnvMan envCacheOwner; public string Module => Mod.Key; public string Section => e.Definition.Section; public string Key => e.Definition.Key; public string Description { get { ConfigDescription description = e.Description; return ((description != null) ? description.Description : null) ?? ""; } } public Type Type => e.SettingType; public bool ServerSynced { get; } public bool HfSynced { get; } public bool AnySync { get { if (!ServerSynced) { if (HfSynced && ConfigSync.SyncOtherMods != null) { return ConfigSync.SyncOtherMods.Value; } return false; } return true; } } public ConfigEntryBase Entry => e; public float Min { get; } public float Max { get; } public bool HasRange { get; } public bool EnvName { get; } public object[] Choices { get { if (!EnvName) { return fixedChoices; } List<string> list = EnvNames(); if (list == null) { return null; } List<object> list2 = new List<object> { "" }; string text = Boxed as string; if (!string.IsNullOrEmpty(text) && !list.Contains(text)) { list2.Add(text); } list2.AddRange(list); return list2.ToArray(); } } public bool RestartHint { get; } public object DefaultBoxed => e.DefaultValue; public object Boxed { get { try { return e.BoxedValue; } catch { return e.DefaultValue; } } set { try { e.BoxedValue = value; if (!e.ConfigFile.SaveOnConfigSet) { ForeignMods.QueueSave(e.ConfigFile); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[OtherMods] " + Mod.Name + " › " + Key + ": could not set value: " + ex.Message)); } } } public string ChoiceLabel(object v) { string text = v as string; if (string.IsNullOrEmpty(text)) { return "(none)"; } if (!EnvName || envBiomes == null || !envBiomes.TryGetValue(text, out var value)) { return text; } return text + " <size=12><color=#999180>" + value + "</color></size>"; } private static List<string> EnvNames() { EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null || instance.m_environments == null) { return null; } if (envCache == null || (Object)(object)envCacheOwner != (Object)(object)instance || envCache.Count == 0) { envCacheOwner = instance; envCache = (from x in instance.m_environments where x != null && !string.IsNullOrEmpty(x.m_name) select x.m_name into x where x != "VoxelUnderground" select x).Distinct().OrderBy<string, string>((string x) => x, StringComparer.OrdinalIgnoreCase).ToList(); envBiomes = new Dictionary<string, string>(); try { Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); foreach (BiomeEnvSetup item2 in instance.m_biomes ?? new List<BiomeEnvSetup>()) { foreach (EnvEntry item3 in item2?.m_environments ?? new List<EnvEntry>()) { if (item3 != null && !string.IsNullOrEmpty(item3.m_environment)) { if (!dictionary.TryGetValue(item3.m_environment, out var value)) { value = (dictionary[item3.m_environment] = new List<string>()); } string item = Widgets.Nice(((object)Unsafe.As<Biome, Biome>(ref item2.m_biome)/*cast due to .constrained prefix*/).ToString()); if (!value.Contains(item)) { value.Add(item); } } } } foreach (KeyValuePair<string, List<string>> item4 in dictionary) { envBiomes[item4.Key] = ((item4.Value.Count > 2) ? (item4.Value[0] + ", " + item4.Value[1] + " +" + (item4.Value.Count - 2)) : string.Join(", ", item4.Value)); } } catch { } } if (envCache.Count <= 0) { return null; } return envCache; } public void Reset() { Boxed = e.DefaultValue; } public bool CanEdit() { if (!AnySync || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { return true; } return ZNet.instance.LocalPlayerIsAdminOrHost(); } internal ForeignOption(ForeignMod mod, ConfigEntryBase entry, bool synced) { Mod = mod; e = entry; ServerSynced = synced; HayKey = (mod.Guid ?? mod.Key) + "|" + entry.Definition.Section + "|" + entry.Definition.Key; ConfigDescription description = entry.Description; AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null); if (val != null) { Type type = ((object)val).GetType(); if (type.Name.StartsWith("AcceptableValueRange") && (Type == typeof(int) || Type == typeof(float))) { try { Min = Convert.ToSingle(type.GetProperty("MinValue").GetValue(val)); Max = Convert.ToSingle(type.GetProperty("MaxValue").GetValue(val)); HasRange = Max > Min; } catch { } } else if (type.Name.StartsWith("AcceptableValueList")) { try { fixedChoices = ((IEnumerable)type.GetProperty("AcceptableValues").GetValue(val)).Cast<object>().ToArray(); } catch { } } } string description2 = Description; ConfigDescription description3 = entry.Description; string text = (description2 + " " + string.Join(" ", ((description3 == null) ? null : description3.Tags?.Select((object x) => x?.ToString() ?? "")) ?? new string[0])).ToLowerInvariant(); if (Type == typeof(string) && fixedChoices == null) { string text2 = (Section + " " + Key).ToLowerInvariant(); EnvName = text.Contains("envman") || (text.Contains("environment") && (text.Contains("name") || text.Contains("preset"))) || text2.Contains("environment") || text2.EndsWith(" env"); } if (!synced) { HfSynced = ForeignMod.GameplayServerSetting(Section, Key, Type, text); } RestartHint = text.Contains("restart") || text.Contains("relog") || text.Contains("reload") || text.Contains("requires a new world") || text.Contains("re-log"); } } public sealed class ForeignMod { public string Guid; public string Name; public string Version; public string Key; public readonly List<ForeignOption> Options = new List<ForeignOption>(); public string SyncSource = "none"; private static readonly string[] LocalSections = new string[16] { "debug", "diagnostic", "visual", "graphic", "audio", "sound", "ui", "uis", "hud", "control", "key", "input", "camera", "about", "client", "local" }; public bool AnySynced => Options.Any((ForeignOption o) => o.ServerSynced); internal static bool GameplayServerSetting(string section, string key, Type t, string desc) { if (t == typeof(KeyCode) || t == typeof(KeyboardShortcut) || t == typeof(Color)) { return false; } string text = section.ToLowerInvariant(); if (Regex.Split(text, "[^a-z]+").Any((string w) => LocalSections.Any((string x) => w.StartsWith(x)))) { return false; } if (desc.Contains("local only") || desc.Contains("client only") || desc.Contains("never synced") || desc.Contains("currently selected")) { return false; } if (!desc.Contains("server setting") && !desc.Contains("server-side setting") && !text.Contains("balance") && !(text == "server")) { return text.StartsWith("server "); } return true; } } public static class ForeignMods { private static readonly string[] Libraries = new string[7] { "jotunn", "yamldotnet", "conditionalconfigsync", "serversync", "bepinex", "harmony", "mmhook" }; private static List<ForeignMod> cache; private static float scannedAt = -999f; private static readonly HashSet<ConfigFile> watched = new HashSet<ConfigFile>(); private static readonly HashSet<ConfigFile> pendingSave = new HashSet<ConfigFile>(); private static float lastQueued; public static List<ForeignMod> All { get { if (cache == null || Time.unscaledTime - scannedAt > 10f) { cache = Scan(); scannedAt = Time.unscaledTime; } return cache; } } public static event Action Changed; public static void QueueSave(ConfigFile f) { pendingSave.Add(f); lastQueued = Time.unscaledTime; } public static void FlushSaves(float settle = 0f) { if (pendingSave.Count == 0 || Time.unscaledTime - lastQueued < settle) { return; } foreach (ConfigFile item in pendingSave) { try { item.Save(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[OtherMods] save failed: " + ex.Message)); } } pendingSave.Clear(); } public static ForeignMod Find(string key) { return All.FirstOrDefault((ForeignMod m) => m.Key == key); } private static List<ForeignMod> Scan() { List<ForeignMod> list = new List<ForeignMod>(); Dictionary<string, PluginInfo> pluginInfos; try { pluginInfos = Chainloader.PluginInfos; } catch { return list; } foreach (KeyValuePair<string, PluginInfo> item in pluginInfos.ToList()) { try { PluginInfo value = item.Value; BaseUnityPlugin val = ((value != null) ? value.Instance : null); if ((Object)(object)val == (Object)null || value.Metadata == null || value.Metadata.GUID == "spencer.hearthforge") { continue; } ConfigFile cfg; try { cfg = val.Config; } catch { goto end_IL_0030; } if (cfg == null) { continue; } List<ConfigEntryBase> list2 = (from x in ((IEnumerable<ConfigDefinition>)cfg.Keys).Select((Func<ConfigDefinition, ConfigEntryBase>)delegate(ConfigDefinition k) { try { return cfg[k]; } catch { return (ConfigEntryBase)null; } }) where x != null select x).ToList(); if (list2.Count == 0) { continue; } string id = (value.Metadata.GUID + " " + value.Metadata.Name).ToLowerInvariant(); if (Libraries.Any((string l) => id.Contains(l)) && list2.Count((ConfigEntryBase x) => x.SettingType == typeof(bool) || x.SettingType.IsEnum || x.SettingType == typeof(KeyCode) || x.SettingType == typeof(KeyboardShortcut)) < 3) { continue; } ForeignMod foreignMod = new ForeignMod { Guid = value.Metadata.GUID, Name = value.Metadata.Name, Version = (value.Metadata.Version?.ToString() ?? ""), Key = "ext:" + value.Metadata.GUID }; Func<ConfigEntryBase, bool> func = SyncProbe(value, ((object)val).GetType().Assembly); foreach (ConfigEntryBase item2 in from x in list2 orderby x.Definition.Section, x.Definition.Key select x) { bool synced; try { synced = func(item2); } catch { synced = true; } foreignMod.Options.Add(new ForeignOption(foreignMod, item2, synced)); } Options.DisplayNames[foreignMod.Key] = foreignMod.Name; if (watched.Add(cfg)) { cfg.SettingChanged += delegate { ForeignMods.Changed?.Invoke(); }; } list.Add(foreignMod); end_IL_0030:; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[OtherMods] skipped " + item.Key + ": " + ex.Message)); } } return list.OrderBy<ForeignMod, string>((ForeignMod m) => m.Name, StringComparer.OrdinalIgnoreCase).ToList(); } private static Func<ConfigEntryBase, bool> SyncProbe(PluginInfo info, Assembly asm) { Type type = null; try { type = asm.GetType("ServerSync.ConfigSync"); } catch { } if (type != null) { Dictionary<ConfigEntryBase, bool> flags = new Dictionary<ConfigEntryBase, bool>(); try { if (type.GetField("configSyncs", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is IEnumerable enumerable) { foreach (object item in enumerable) { if (!(item.GetType().GetField("allConfigs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(item) is IEnumerable enumerable2)) { continue; } foreach (object item2 in enumerable2) { Type type2 = item2.GetType(); object? obj2 = type2.GetField("BaseConfig")?.GetValue(item2) ?? type2.GetProperty("BaseConfig")?.GetValue(item2); ConfigEntryBase val = (ConfigEntryBase)((obj2 is ConfigEntryBase) ? obj2 : null); object obj3 = type2.GetField("SynchronizedConfig")?.GetValue(item2) ?? type2.GetProperty("SynchronizedConfig")?.GetValue(item2); if (val != null && obj3 is bool value) { flags[val] = value; } } } } } catch { } bool value2; if (flags.Count > 0) { return (ConfigEntryBase en) => flags.TryGetValue(en, out value2) && value2; } return (ConfigEntryBase _) => true; } bool flag = false; try { flag = info.Dependencies != null && info.Dependencies.Any((BepInDependency d) => d.DependencyGUID.IndexOf("ConditionalConfigSync", StringComparison.OrdinalIgnoreCase) >= 0); } catch { } if (flag) { return (ConfigEntryBase _) => true; } return delegate(ConfigEntryBase en) { ConfigDescription description = en.Description; object[] array = ((description != null) ? description.Tags : null); if (array == null) { return false; } object[] array2 = array; bool flag2 = default(bool); foreach (object obj6 in array2) { if (obj6 != null) { Type type3 = obj6.GetType(); FieldInfo fieldInfo = type3.GetField("IsAdminOnly") ?? null; PropertyInfo propertyInfo = ((fieldInfo == null) ? type3.GetProperty("IsAdminOnly") : null); object obj7 = ((fieldInfo != null) ? fieldInfo.GetValue(obj6) : propertyInfo?.GetValue(obj6)); int num; if (obj7 is bool) { flag2 = (bool)obj7; num = 1; } else { num = 0; } if (((uint)num & (flag2 ? 1u : 0u)) != 0) { return true; } } } return false; }; } } public class ShortcutRow : OptionRow, IBuildable { private Button b; private TextMeshProUGUI label; private static KeyCode[] codes; private int startFrame; private static readonly KeyCode[] Mods; public static ShortcutRow capturing; public static bool Busy => (Object)(object)capturing != (Object)null; public void Build(RectTransform ctl, Transform _) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Theme.Rect("Key", (Transform)(object)ctl); Theme.Place(val, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(220f, 34f)); b = Widgets.Button((Transform)(object)val, "", delegate { if (base.Editable) { KeybindRow.Capturing = null; capturing = this; startFrame = Time.frameCount; } }); label = ((Component)b).GetComponentInChildren<TextMeshProUGUI>(); if (codes == null) { codes = ((KeyCode[])Enum.GetValues(typeof(KeyCode))).Where((KeyCode k) => (int)k != 0 && (int)k < 330 && !Mods.Contains(k)).Distinct().ToArray(); } } public unsafe override void Refresh() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Widgets.SetInteractable((Selectable)(object)b, base.Editable); KeyboardShortcut val = ((Option.Boxed is KeyboardShortcut val2) ? val2 : KeyboardShortcut.Empty); ((TMP_Text)label).text = (((Object)(object)capturing == (Object)(object)this) ? "Press keys…" : ("[ " + (((int)((KeyboardShortcut)(ref val)).MainKey == 0) ? "None" : ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString()) + " ]")); } private void Update() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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) if ((Object)(object)capturing != (Object)(object)this) { return; } ((TMP_Text)label).text = "Press keys… (Esc cancel, Bksp clear)"; ((Graphic)label).color = Color.Lerp(Theme.Gold, Theme.Parchment, Mathf.PingPong(Time.unscaledTime * 2f, 1f)); if (Time.frameCount < startFrame + 2) { return; } KeyCode[] array = codes; foreach (KeyCode val in array) { if (Widgets.KeyDown(val)) { if ((int)val == 8) { Option.Boxed = KeyboardShortcut.Empty; } else if ((int)val != 27) { Option.Boxed = (object)new KeyboardShortcut(val, Mods.Where(Widgets.KeyHeld).ToArray()); } capturing = null; ((Graphic)label).color = Theme.Gold; SettingsPanel.SwallowEscapeFrame = Time.frameCount; Refresh(); break; } } } private void OnDisable() { if ((Object)(object)capturing == (Object)(object)this) { capturing = null; } } static ShortcutRow() { KeyCode[] array = new KeyCode[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Mods = (KeyCode[])(object)array; } } public class ColorRow : OptionRow, IBuildable { private Image sw; private TMP_InputField f; public void Build(RectTransform ctl, Transform _) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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) RectTransform val = Theme.Rect("Swatch", (Transform)(object)ctl); Theme.Place(val, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-150f, 0f), new Vector2(34f, 30f)); Theme.Img((Component)(object)val, Theme.Slot, Color.white); sw = Theme.Img((Component)(object)Theme.Fill("Fill", (Transform)(object)val, 5f), null, Color.white, sliced: false, raycast: false); RectTransform val2 = Theme.Rect("Hex", (Transform)(object)ctl); Theme.Place(val2, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, new Vector2(140f, 34f)); f = Widgets.Input((Transform)(object)val2, "#RRGGBBAA"); f.textComponent.alignment = (TextAlignmentOptions)514; ((UnityEvent<string>)(object)f.onEndEdit).AddListener((UnityAction<string>)delegate(string txt) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!base.Editable) { Refresh(); } else { string text = txt.Trim(); if (!text.StartsWith("#")) { text = "#" + text; } Color val3 = default(Color); if (ColorUtility.TryParseHtmlString(text, ref val3)) { Option.Boxed = val3; } Refresh(); } }); } public override void Refresh() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) Color val = ((Option.Boxed is Color val2) ? val2 : Color.white); ((Graphic)sw).color = val; ((Selectable)f).interactable = base.Editable; if (!f.isFocused) { f.text = "#" + ColorUtility.ToHtmlStringRGBA(val); } } } public static class Gilded { public class StayOnTop : MonoBehaviour { private void Start() { ((Component)this).transform.SetAsLastSibling(); } private void OnTransformParentChanged() { ((Component)this).transform.SetAsLastSibling(); } private void OnEnable() { ((Component)this).transform.SetAsLastSibling(); } } private static readonly Dictionary<(string, float, bool), Sprite> cache = new Dictionary<(string, float, bool), Sprite>(); private static readonly HashSet<string> missing = new HashSet<string>(); public const float WindowScale = 0.6f; public static bool Pref = true; public static readonly Color Gold = Theme.Gold; public static readonly Color Amber = Theme.Amber; public static readonly Color Text = Theme.Text; public static Sprite Frame => Load("g_frame", 52f); public static Sprite Slot => Load("g_slot", 24f); public static Sprite Banner => Load("g_banner", 44f); public static Sprite BarBg => Load("g_bar_bg", 9f); public static Sprite BarFill => Load("g_bar_fill", 9f); public static Sprite Frame2 => Load("g2_frame", 84f); public static Sprite Title2 => Load("g2_title", 170f); public static Sprite Plaque2 => Load("g2_plaque", 30f); public static Sprite Slot2 => Load("g2_slot", 24f); public static Sprite Hover2 => Load("g2_hover", 24f); public static Sprite Glow2 => Load("g2_glow", 0f); public static Sprite Divider2 => Load("g2_divider", 0f); public static Sprite BarBg2 => Load("g2_bar_bg", 11f); public static Sprite BarFill2 => Load("g2_bar_fill", 11f); public static Sprite Hearth128 => Load("hearth_128", 0f); public static Sprite Hearth64 => Load("hearth_64", 0f); public static Sprite FrameSmall => Load("g_frame", 52f, 290f); public static Sprite SlotSmall => Load("g_slot", 24f, 340f); public static Sprite SlotMid => Load("g_slot", 24f, 200f); public static Sprite Window => G3("g3_window", 152f); public static Sprite WindowCorners => G3("g3_window_corners", 152f); public static Sprite Frame3 => G3("g3_frame", 36f); public static Sprite Inset => G3("g3_inset", 30f); public static Sprite InsetSmall => G3("g3_inset", 30f, 400f); public static Sprite Row => G3("g3_row", 24f); public static Sprite Button => G3("g3_button", 16f); public static Sprite ButtonPress => G3("g3_button_press", 16f); public static Sprite ButtonGlow => G3("g3_button_glow", 16f); public static Sprite Tab => G3("g3_tab", 20f); public static Sprite TabSel => G3("g3_tab_sel", 20f); public static Sprite Toggle => G3("g3_toggle", 27f); public static Sprite ToggleFill => G3("g3_toggle_fill", 27f); public static Sprite Knob => G3("g3_knob", 0f); public static Sprite KnobSmall => G3("g3_knob_small", 0f); public static Sprite SliderTrack => G3("g3_slider_track", 17f); public static Sprite SliderFill => G3("g3_slider_fill", 11f); public static Sprite Input => G3("g3_input", 12f); public static Sprite Header => G3("g3_header", 60f); public static Sprite TitleBar => G3("g3_titlebar", 16f); public static Sprite Crest => G3("g3_crest", 0f); public static Sprite Title3 => G3("g3_title", 200f); public static Sprite Slot3 => G3("g3_slot", 22f); public static Sprite Ring3 => G3("g3_ring", 0f); public static Sprite SlotHover3 => G3("g3_slot_hover", 22f); public static Sprite Glow3 => G3("g3_glow", 0f); public static Sprite Divider3 => G3("g3_divider", 0f); public static Sprite BarBg3 => G3("g3_bar_bg", 12f); public static Sprite BarFill3 => G3("g3_bar_fill", 6f); public static Sprite BarGold3 => G3("g3_bar_gold", 6f); public static Sprite Scroll => G3("g3_scroll", 8f); public static Sprite Chevron => G3("g3_chevron", 0f); public static Sprite Load(string name, float border, float ppu = 100f) { return Load(name, border, ppu, mips: false); } public static Sprite Load(string name, float border, float ppu, bool mips) { //IL_00bf: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) (string, float, bool) key = (name, ppu, mips); if (cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } if (missing.Contains(name)) { return null; } try { using Stream stream = typeof(Gilded).Assembly.GetManifestResourceStream("Hearthforge.assets." + name + ".png"); if (stream == null) { missing.Add(name); Plugin.Log.LogWarning((object)("[Gilded] missing embedded art " + name)); return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, mips) { name = "HF_" + name, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, anisoLevel = 0 }; if (!ImageConversion.LoadImage(val, array, mips)) { missing.Add(name); return null; } ((Texture)val).filterMode = (FilterMode)((!mips) ? 1 : 2); ((Texture)val).wrapMode = (TextureWrapMode)1; if (mips) { ((Texture)val).mipMapBias = -0.35f; } float num2 = Mathf.Min(border, (float)((Texture)val).width / 2f - 1f); float num3 = Mathf.Min(border, (float)((Texture)val).height / 2f - 1f); value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), ppu, 0u, (SpriteMeshType)0, new Vector4(num2, num3, num2, num3)); ((Object)value).name = "HF_" + name; cache[key] = value; return value; } catch (Exception ex) { missing.Add(name); Plugin.Log.LogWarning((object)("[Gilded] could not load " + name + ": " + ex.Message)); return null; } } private static Sprite G3(string n, float border, float ppu = 200f) { if (!Pref) { return null; } return Load(n, border, ppu, mips: true); } public static void Fit(Image img, Sprite s, float screenBorder = 0f) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)img == (Object)null) && !((Object)(object)s == (Object)null)) { img.sprite = s; float num = Mathf.Max(s.border.x, s.border.y); if (num <= 0f) { img.type = (Type)0; return; } img.type = (Type)1; img.fillCenter = true; img.pixelsPerUnitMultiplier = ((screenBorder > 0f) ? (num * 100f / s.pixelsPerUnit / screenBorder) : 1f); } } public static Image WindowBg(RectTransform w) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Image val = ((Component)w).GetComponent<Image>() ?? ((Component)w).gameObject.AddComponent<Image>(); if ((Object)(object)Window == (Object)null) { val.sprite = Theme.Frame; val.type = (Type)1; ((Graphic)val).color = Color.white; Theme.Shadow((Component)(object)val, 8f); return val; } ((Graphic)val).color = Color.white; ((Graphic)val).raycastTarget = true; val.sprite = Window; val.type = (Type)1; val.fillCenter = true; val.pixelsPerUnitMultiplier = 1.6666666f; RectTransform component = new GameObject("GildedCorners", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)w, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; Image obj = ((Component)component).gameObject.AddComponent<Image>(); obj.sprite = WindowCorners; obj.type = (Type)1; obj.fillCenter = false; obj.pixelsPerUnitMultiplier = 1.6666666f; ((Graphic)obj).raycastTarget = false; ((Component)component).gameObject.AddComponent<StayOnTop>(); return val; } public static void Apply(Image img, Sprite s, float screenBorder, float texBorder) { if (!((Object)(object)img == (Object)null) && !((Object)(object)s == (Object)null)) { img.sprite = s; img.type = (Type)1; img.fillCenter = true; img.pixelsPerUnitMultiplier = ((texBorder > 0f && screenBorder > 0f) ? (texBorder / screenBorder) : 1f); } } } public static class HfCanvas { private sealed class Entry { public CanvasScaler S; public float Match; } public static ModOption<bool> Follow; private static readonly List<Entry> list = new List<Entry>(); private static float nextCheck; private static float lastFactor = -1f; private static int lastW; private static int lastH; private static bool lastOn; private static float guiCached = 1f; private static float guiAt = -1f; private static bool On { get { if (Follow != null) { return Follow.Value; } return true; } } public static float GuiScaleIfFollowing { get { if (!On) { return 1f; } return GameGuiScale(); } } internal static event Action Changed; internal static void Bind() { Follow = Options.Bind("UI", "FollowGameGuiScale", def: true, "Hearthforge windows and HUD follow the game's GUI scale (Settings › Accessibility › GUI scale), so they match vanilla's size on every screen shape. At 16:9 and 100 % nothing changes. Off = the old fixed 1920x1080 scaling", synced: false); Follow.Changed += delegate { lastFactor = -1f; ApplyAll(); }; } public static void Register(CanvasScaler sc) { if ((Object)(object)sc == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i].S == (Object)(object)sc) { return; } } Entry entry = new Entry { S = sc, Match = sc.matchWidthOrHeight }; list.Add(entry); Apply(entry, Factor()); } private static float GameGuiScale() { if (Time.unscaledTime < guiAt) { return guiCached; } guiAt = Time.unscaledTime + 0.5f; try { guiCached = Mathf.Clamp(PlatformPrefs.GetFloat("GuiScale", 1f), 0.5f, 3f); } catch { guiCached = 1f; } return guiCached; } private static float Factor() { return Mathf.Max(0.1f, Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * GameGuiScale()); } private static void Apply(Entry e, float f) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) CanvasScaler s = e.S; if ((Object)(object)s == (Object)null) { return; } if (On) { if ((int)s.uiScaleMode != 0) { s.uiScaleMode = (ScaleMode)0; } if (Mathf.Abs(s.scaleFactor - f) > 0.0001f) { s.scaleFactor = f; } } else if ((int)s.uiScaleMode != 1) { s.uiScaleMode = (ScaleMode)1; s.referenceResolution = new Vector2(1920f, 1080f); s.matchWidthOrHeight = e.Match; } } private static void ApplyAll() { float f = Factor(); for (int num = list.Count - 1; num >= 0; num--) { if ((Object)(object)list[num].S == (Object)null) { list.RemoveAt(num); } else { Apply(list[num], f); } } lastFactor = f; lastW = Screen.width; lastH = Screen.height; lastOn = On; try { HfCanvas.Changed?.Invoke(); } catch { } } internal static void Tick() { if (list.Count != 0 && !(Time.unscaledTime < nextCheck)) { nextCheck = Time.unscaledTime + 1f; if (Screen.width != lastW || Screen.height != lastH || On != lastOn || Mathf.Abs(Factor() - lastFactor) > 0.0001f) { ApplyAll(); } } } } [HarmonyPatch] internal static class InputBlock { private static readonly FieldRef<GameObject> tooltipObj = AccessTools.StaticFieldRefAccess<GameObject>(AccessTools.Field(typeof(UITooltip), "m_tooltip")); private static bool Blocking { get { if (!SettingsPanel.IsOpen && !HudModule.EditMode && !ItemPicker.AnyOpen && !ZoneResetModule.DialogOpen && !BackpackModule.PromptOpen && !DyeModule.PanelOpen && !FermenterModule.PanelOpen && !HomesteadModule.BpWindow.IsOpen && !SignStyleModule.Editor.IsOpen && !HomesteadModule.UnpackWindow.IsOpen && !HomesteadModule.PackSummary.IsOpen && !KilnGuard.Confirm.IsOpen && !StringEditor.IsOpen && !ConfirmDialog.IsOpen && !ShipStyleModule.Picker.IsOpen) { return SocialModule.SocialWindow.IsOpen; } return true; } } internal static bool Any => Blocking; [HarmonyPostfix] [HarmonyPatch(typeof(Menu), "IsVisible")] private static void Visible(ref bool __result) { if (Blocking) { __result = true; } } [HarmonyPostfix] [HarmonyPatch(typeof(Menu), "IsActive")] private static void Active(ref bool __result) { if (Blocking) { __result = true; } } [HarmonyPostfix] [HarmonyPatch(typeof(UITooltip), "OnHoverStart")] private static void Reparent(UITooltip __instance) { GameObject val = tooltipObj.Invoke(); if ((Object)(object)val == (Object)null) { return; } Canvas componentInParent = ((Component)__instance).GetComponentInParent<Canvas>(); if (!((Object)(object)componentInParent == (Object)null)) { Transform transform = ((Component)componentInParent.rootCanvas).transform; if ((Object)(object)val.transform.parent != (Object)(object)transform) { val.transform.SetParent(transform, false); } val.transform.SetAsLastSibling(); CanvasGroup obj = val.GetComponent<CanvasGroup>() ?? val.AddComponent<CanvasGroup>(); obj.blocksRaycasts = false; obj.interactable = false; } } [HarmonyPrefix] [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static bool Cursor() { if (!Blocking) { return true; } if ((Object)(object)EventSystem.current == (Object)null) { UiFocus.Grab(); } ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Menu), "Update")] private static bool NoPauseMenu() { if (!Blocking) { return SettingsPanel.SwallowEscapeFrame != Time.frameCount; } return false; } } public class ItemPicker : MonoBehaviour { private static readonly HashSet<ItemPicker> open = new HashSet<ItemPicker>(); public string Title = "Items"; public Func<ItemDrop, bool> Filter = (ItemDrop _) => true; public Func<ItemDrop, bool> IsSelected = (ItemDrop _) => false; public Action<ItemDrop> OnClick; public string SelectedHeader = "Selected"; public Action OnClosed; public List<(string label, Action act)> ExtraButtons = new List<(string, Action)>(); private GameObject canvasGo; private RectTransform resultContent; private RectTransform selectedContent; private TMP_InputField search; private TextMeshProUGUI countText; private TextMeshProUGUI titleLabel; private TextMeshProUGUI selHeader; private List<ItemDrop> all; private const int MaxResults = 240; public static bool AnyOpen => open.Count > 0; public bool IsOpen { get { if ((Object)(object)canvasGo != (Object)null) { return canvasGo.activeSelf; } return false; } } public static ItemPicker Create(string name) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown GameObject val = new GameObject("HF_ItemPicker_" + name); Object.DontDestroyOnLoad((Object)val); return val.AddComponent<ItemPicker>(); } public void Toggle() { if (IsOpen) { Close(); } else { Open(); } } public void Open() { if (!((Object)(object)ObjectDB.instance == (Object)null)) { if ((Object)(object)canvasGo == (Object)null) { Build(); } all = (from g in ObjectDB.instance.m_items where (Object)(object)g != (Object)null select g.GetComponent<ItemDrop>() into d where (Object)(object)d != (Object)null && d.m_itemData?.m_shared != null && d.m_itemData.m_shared.m_icons != null && d.m_itemData.m_shared.m_icons.Length != 0 orderby Util.Loc(d.m_itemData.m_shared.m_name) select d).ToList(); canvasGo.SetActive(true); open.Add(this); ((TMP_Text)titleLabel).text = Title; ((TMP_Text)selHeader).text = SelectedHeader; search.text = ""; Refresh(); } } public void Close() { if ((Object)(object)canvasGo != (Object)null) { canvasGo.SetActive(false); } open.Remove(this); UITooltip.HideTooltip(); OnClosed?.Invoke(); } private void Update() { if (IsOpen && ZInput.GetKeyDown((KeyCode)27, false)) { Close(); SettingsPanel.SwallowEscapeFrame = Time.frameCount; } if (IsOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void Build() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0514: Unknown result type (might be due to invalid IL or missing references) canvasGo = new GameObject("Canvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); canvasGo.transform.SetParent(((Component)this).transform, false); Canvas component = canvasGo.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 30010; CanvasScaler component2 = canvasGo.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.matchWidthOrHeight = 0.5f; HfCanvas.Register(component2); RectTransform val = Theme.Rect("Window", canvasGo.transform); Theme.Place(val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1000f, 680f)); Gilded.WindowBg(val); RectTransform val2 = Theme.Rect("Title", (Transform)(object)val, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(10f, -60f), new Vector2(-10f, -10f)); Theme.TitleBarImg((Component)(object)val2); ((Component)val2).gameObject.AddComponent<Draggable>().Target = val; titleLabel = Theme.Label((Transform)(object)val2, Title, 28f, Theme.Gold, (TextAlignmentOptions)513, header: true); ((TMP_Text)titleLabel).rectTransform.offsetMin = new Vector2(16f, 0f); RectTransform obj = Theme.Rect("Close", (Transform)(object)val2); Theme.Place(obj, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-8f, 0f), new Vector2(40f, 36f)); Widgets.Button((Transform)(object)obj, "x", Close, 20f); RectTransform val3 = Theme.Rect("Search", (Transform)(object)val2); Theme.Place(val3, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-56f, 0f), new Vector2(300f, 34f)); search = Widgets.Input((Transform)(object)val3, "Search all items…"); ((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate { Refresh(); }); float num = -364f; foreach (var extraButton in ExtraButtons) { string item = extraButton.label; Action item2 = extraButton.act; RectTransform obj2 = Theme.Rect("Btn", (Transform)(object)val2); Theme.Place(obj2, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(num, 0f), new Vector2(110f, 34f)); Action a = item2; Widgets.Button((Transform)(object)obj2, item, delegate { a(); Refresh(); }, 14f); num -= 116f; } RectTransform val4 = Theme.Rect("Results", (Transform)(object)val, new Vector2(0f, 0f), new Vector2(0.64f, 1f), new Vector2(14f, 40f), new Vector2(-6f, -70f)); Theme.Img((Component)(object)val4, Theme.Slot, Color.white); resultContent = Scroll(val4, grid: true); RectTransform val5 = Theme.Rect("Selected", (Transform)(object)val, new Vector2(0.64f, 0f), new Vector2(1f, 1f), new Vector2(6f, 40f), new Vector2(-14f, -100f)); Theme.Img((Component)(object)val5, Theme.Slot, Color.white); RectTransform parent = Theme.Rect("Header", (Transform)(object)val, new Vector2(0.64f, 1f), new Vector2(1f, 1f), new Vector2(6f, -98f), new Vector2(-14f, -70f)); selHeader = Theme.Label((Transform)(object)parent, SelectedHeader, 18f, Theme.Gold, (TextAlignmentOptions)513, header: true); ((TMP_Text)selHeader).rectTransform.offsetMin = new Vector2(8f, 0f); selectedContent = Scroll(val5, grid: false); RectTransform parent2 = Theme.Rect("Foot", (Transform)(object)val, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(18f, 8f), new Vector2(-18f, 36f)); countText = Theme.Label((Transform)(object)parent2, "", 13f, Theme.TextDim, (TextAlignmentOptions)513); canvasGo.SetActive(false); } private static RectTransform Scroll(RectTransform parent, bool grid) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) ScrollRect obj = ((Component)parent).gameObject.AddComponent<ScrollRect>(); obj.horizontal = false; obj.scrollSensitivity = 30f; SmoothScroll.Attach(obj); RectTransform val = Theme.Fill("Viewport", (Transform)(object)parent, 6f); ((Component)val).gameObject.AddComponent<RectMask2D>(); RectTransform val2 = Theme.Rect("Content", (Transform)(object)val); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(1f, 1f); val2.pivot = new Vector2(0.5f, 1f); Vector2 offsetMin = (val2.offsetMax = Vector2.zero); val2.offsetMin = offsetMin; if (grid) { GridLayoutGroup obj2 = ((Component)val2).gameObject.AddComponent<GridLayoutGroup>(); obj2.cellSize = new Vector2(196f, 52f); obj2.spacing = new Vector2(6f, 6f); } else { VerticalLayoutGroup obj3 = ((Component)val2).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; } ((Component)val2).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; obj.viewport = val; obj.content = val2; return val2; } public void Refresh() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!IsOpen) { return; } foreach (Transform item in (Transform)resultContent) { Object.Destroy((Object)(object)((Component)item).gameObject); } foreach (Transform item2 in (Transform)selectedContent) { Object.Destroy((Object)(object)((Component)item2).gameObject); } string q = search.text.Trim(); List<ItemDrop> list = all.Where((ItemDrop d) => Filter(d) && (q.Length == 0 || Util.Loc(d.m_itemData.m_shared.m_name).IndexOf(q, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)d).name.IndexOf(q, StringComparison.OrdinalIgnoreCase) >= 0)).ToList(); foreach (ItemDrop item3 in list.Take(240)) { Entry((Transform)(object)resultContent, item3, 196f); } List<ItemDrop> list2 = all.Where(IsSelected).ToList(); foreach (ItemDrop item4 in list2) { Entry((Transform)(object)selectedContent, item4, 0f); } ((TMP_Text)countText).text = string.Format("{0} items match{1} · {2} selected · click an item to toggle", list.Count, (list.Count > 240) ? $" (showing {240}, refine your search)" : "", list2.Count); } private void Entry(Transform parent, ItemDrop d, float w) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Theme.Rect("Item", parent); val.sizeDelta = new Vector2(w, 52f); bool flag = IsSelected(d); Image targetGraphic = Theme.Img((Component)(object)val, Theme.Slot, (Color)(flag ? new Color(1f, 0.85f, 0.45f) : Color.white)); Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)targetGraphic; ColorBlock colors = ((Selectable)obj).colors; ((ColorBlock)(ref colors)).highlightedColor = new Color(1.3f, 1.2f, 1f); ((Selectable)obj).colors = colors; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { OnClick?.Invoke(d); Refresh(); }); RectTransform obj2 = Theme.Rect("Icon", (Transform)(object)val); Theme.Place(obj2, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(6f, 0f), new Vector2(42f, 42f)); Theme.Img((Component)(object)obj2, d.m_itemData.GetIcon(), Color.white, sliced: false, raycast: false).preserveAspect = true; TextMeshProUGUI obj3 = Theme.Label((Transform)(object)val, Util.Loc(d.m_itemData.m_shared.m_name), 15f, flag ? Theme.Gold : Theme.Text, (TextAlignmentOptions)513); ((TMP_Text)obj3).rectTransform.offsetMin = new Vector2(54f, 0f); ((TMP_Text)obj3).rectTransform.offsetMax = new Vector2(-4f, 0f); GameObject val2 = Widgets.TooltipPrefab(); if ((Object)(object)val2 != (Object)null) { UITooltip obj4 = ((Component)val).gameObject.AddComponent<UITooltip>(); obj4.m_tooltipPrefab = val2; obj4.m_topic = d.m_itemData.m_shared.m_name; obj4.m_text = ((Object)d).name; } } } public static class RuneFont { private static TMP_FontAsset font; private static bool tried; public static TMP_FontAsset Font { get { Ensure(); return font; } } public static void Ensure() { if (tried) { return; } tried = true; try { string text = Path.Combine(Paths.CachePath, "Hearthforge-NotoSansRunic-Regular.ttf"); using (Stream stream = typeof(RuneFont).Assembly.GetManifestResourceStream("Hearthforge.assets.NotoSansRunic-Regular.ttf")) { if (stream == null) { Plugin.Log.LogWarning((object)"[Runes] rune font missing from the DLL"); return; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (!File.Exists(text) || new FileInfo(text).Length != array.Length) { Directory.CreateDirectory(Path.GetDirectoryName(text)); File.WriteAllBytes(text, array); } } font = TMP_FontAsset.CreateFontAsset(text, 0, 64, 6, (GlyphRenderMode)4165, 512, 512); if ((Object)(object)font == (Object)null) { Plugin.Log.LogWarning((object)"[Runes] could not create the rune font"); return; } ((Object)font).name = "HF_NotoSansRunic"; StringBuilder stringBuilder = new StringBuilder(); for (int j = 5792; j <= 5880; j++) { stringBuilder.Append((char)j); } string text2 = default(string); font.TryAddCharacters(stringBuilder.ToString(), ref text2, false); List<TMP_FontAsset> fallbackFontAssets = TMP_Settings.fallbackFontAssets; if (fallbackFontAssets != null && !fallbackFontAssets.Contains(font)) { fallbackFontAssets.Add(font); } TMP_FontAsset[] array2 = (TMP_FontAsset[])(object)new TMP_FontAsset[2] { Theme.Body, Theme.Norse }; foreach (TMP_FontAsset val in array2) { if ((Object)(object)val != (Object)null) { if (val.fallbackFontAssetTable == null) { val.fallbackFontAssetTable = new List<TMP_FontAsset>(); } if (!val.fallbackFontAssetTable.Contains(font)) { val.fallbackFontAssetTable.Add(font); } } } Plugin.Log.LogInfo((object)("[Runes] rune font ready (fallback for U+16A0-U+16F8)" + (string.IsNullOrEmpty(text2) ? "" : (", missing " + text2.Length)))); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Runes] rune font: " + ex.Message)); } } } public class SettingsPanel : MonoBehaviour { private sealed class CloseHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public Image Img; public Sprite Normal; public Sprite Hover; public void OnPointerEnter(PointerEventData e) { if ((Object)(object)Img != (Object)null && (Object)(object)Img.sprite != (Object)(object)Hover) { Img.sprite = Hover; } } public void OnPointerExit(PointerEventData e) { if ((Object)(object)Img != (Object)null && (Object)(object)Img.sprite != (Object)(object)Normal) { Img.sprite = Normal; } } private void OnDisable() { if ((Object)(object)Img != (Object)null) { Img.sprite = Normal; } } } public static ModOption<KeyCode> ToggleKey; public static ModOption<float> UiScale; public static ModOption<float> PanelX; public static ModOption<float> PanelY; public static int SwallowEscapeFrame = -1; private GameObject canvasGo; private RectTransform window; private RectTransform tabsContent; private RectTransform listContent; private RectTransform popupLayer; private CanvasGroup group; private TMP_InputField search; private TextMeshProUGUI statusText; private TextMeshProUGUI headerText; private readonly List<OptionRow> rows = new List<OptionRow>(); private readonly Dictionary<string, (Image bg, TextMeshProUGUI txt, Image dot)> tabs = new Dictionary<string, (Image, TextMeshProUGUI, Image)>(); private static ModOption<string> Collapsed; private readonly HashSet<string> advOpen = new HashSet<string>(); private string activeModule; private bool open; private bool dirty; private bool tabsDirty; private bool staffDirty; private bool lastAdminView = true; private bool lastStaffView; private float anim; private readonly Queue<Action> pendingRows = new Queue<Action>(); private static readonly Dictionary<string, string> hayCache = new Dictionary<string, string>(); private static readonly HashSet<string> haySeen = new HashSet<string>(); private static readonly List<string> hayDrop = new List<string>(); private static int hayOthers = -1; private static bool hayHooked; private static readonly Dictionary<IOption, string> hayOwn = new Dictionary<IOption, string>(); private static bool textRefit; private static readonly List<RowFit> fitBuf = new List<RowFit>(); private float fitK = 1f; private float lastK = -1f; private float pendingSearchAt = -1f; private bool tweening; private bool typeDirty; private static bool fitDirty; private float loggedK = -1f; private readonly HashSet<string> secOpen = new HashSet<string>(); private readonly Dictionary<string, RectTransform> secRects = new Dictionary<string, RectTransform>(); private readonly List<RectTransform> secBodies = new List<RectTransform>(); private string staffId = ""; public static SettingsPanel Instance { get; private set; } public static bool IsOpen { get { if ((Object)(object)Instance != (Object)null) { return Instance.open; } return false; } } public static void BindOptions() { HfCanvas.Bind(); Options.KeyNames["Graphics.ReflectionHdr"] = "HDR Reflections"; Options.KeyNames["Graphics.ReflectionSmooth"] = "Smooth Reflection Updates"; if (!hayHooked) { hayHooked = true; Options.ListChanged += delegate { hayCache.Clear(); hayOwn.Clear(); }; } ToggleKey = Options.Bind<KeyCode>("UI", "ToggleKey", (KeyCode)288, "Open/close the Hearthforge settings panel", synced: false); UiScale = Options.Bind("UI", "PanelScale", 1f, "Settings panel scale", synced: false, 0.6f, 1.6f); PanelX = Options.Bind("UI", "PanelX", 0f, "Panel X offset (drag the title bar)", synced: false, -1500f, 1500f); SmoothScroll.Speed = Options.Bind("UI", "ScrollSpeed", 50f, "Mouse-wheel scroll distance per notch in settings and lists (px)", synced: false, 10f, 200f); PanelY = Options.Bind("UI", "PanelY", 0f, "Panel Y offset (drag the title bar)", synced: false, -900f, 900f); UiScale.Changed += delegate { fitDirty = true; }; PanelX.Changed += delegate { fitDirty = true; }; PanelY.Changed += delegate { fitDirty = true; }; HfCanvas.Changed += delegate { fitDirty = true; }; Collapsed = Options.Bind("UI", "CollapsedGroups", string.Join("|", F7Catalog.Categories) + "|Other Mods", "Internal: F7 categories folded shut (|-separated)", synced: false); } private void Awake() { Instance = this; ((BaseUnityPlugin)Plugin.Instance).Config.SettingChanged += delegate { dirty = true; }; Options.ListChanged += delegate { tabsDirty = true; }; ForeignMods.Changed += delegate { dirty = true; }; Staff.Changed += delegate { staffDirty = true; tabsDirty = true; }; } private void Update() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)KeybindRow.Capturing == (Object)null && !ShortcutRow.Busy && (int)ToggleKey.Value != 0 && Widgets.KeyDown(ToggleKey.Value) && !InTextField()) { Toggle(); } else if (open && (Object)(object)KeybindRow.Capturing == (Object)null && (Object)(object)ClickActivate.Editing == (Object)null && !StringEditor.IsOpen && !ShortcutRow.Busy && Widgets.KeyDown((KeyCode)27) && SwallowEscapeFrame != Time.frameCount) { Toggle(); SwallowEscapeFrame = Time.frameCount; } if ((Object)(object)group != (Object)null) { float num = (open ? 1 : 0); float num2 = UiScale.Value * fitK; if (anim != num || num2 != lastK || group.blocksRaycasts != open) { anim = Mathf.MoveTowards(anim, num, Time.unscaledDeltaTime / (open ? 0.18f : 0.12f)); float num3 = 1f - (1f - anim) * (1f - anim); group.alpha = num3; ((Transform)window).localScale = Vector3.one * num2 * (0.96f + 0.04f * num3); group.blocksRaycasts = open; lastK = num2; bool flag = anim != num; if (flag != tweening) { tweening = flag; if (flag) { UiTween.Begin(); } else { UiTween.End(); } } } if (!open && anim <= 0f && canvasGo.activeSelf) { canvasGo.SetActive(false); } } if (open && pendingSearchAt > 0f && Time.unscaledTime >= pendingSearchAt) { pendingSearchAt = -1f; ShowModule(activeModule); } if (open && fitDirty) { fitDirty = false; FitToCanvas(); } if (open && pendingRows.Count > 0) { long timestamp = Stopwatch.GetTimestamp(); long num4 = Stopwatch.Frequency / 1000; int childCount = ((Transform)listContent).childCount; while (pendingRows.Count > 0 && Stopwatch.GetTimestamp() - timestamp < num4) { pendingRows.Dequeue()(); } for (int i = childCount; i < ((Transform)listContent).childCount; i++) { GildedUIModule.TypeNow(((Component)((Transform)listContent).GetChild(i)).gameObject); } } if (!open) { return; } bool adminView = F7Catalog.AdminView; bool staffView = F7Catalog.StaffView; if (adminView != lastAdminView || staffView != lastStaffView) { lastAdminView = adminView; lastStaffView = staffView; tabsDirty = true; dirty = true; if ((!staffView && activeModule == "Staff") || (!adminView && activeModule == "AdminSettings")) { activeModule = null; } ShowModule(activeModule ?? PageOf(F7Catalog.Group().SelectMany(((string cat, List<string> pages) g) => g.pages).FirstOrDefault())); } if ((Object)(object)ZNet.instance != (Object)null && (staffView || activeModule == "Staff")) { Staff.Tick(); } if (staffDirty) { staffDirty = false; if (activeModule == "Staff") { TMP_InputField obj = search; if (string.IsNullOrEmpty((obj != null) ? obj.text : null)) { ShowModule(activeModule); } } } if (tabsDirty) { BuildTabs(); tabsDirty = false; } ForeignMods.FlushSaves(0.5f); if (dirty) { foreach (OptionRow row in rows) { if (Object.op_Implicit((Object)(object)row)) { row.Refresh(); row.RefreshLock(); } } RefreshTabs(); RefreshStatus(); dirty = false; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } private bool InTextField() { EventSystem current = EventSystem.current; GameObject val = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null); if (!StringEditor.IsOpen && !((Object)(object)ClickActivate.Editing != (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)val.GetComponent<TMP_InputField>() != (Object)null) || !val.GetComponent<TMP_InputField>().isFocused) && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus())) { return TextInput.IsVisible(); } return true; } public void Toggle() { if ((Object)(object)canvasGo == (Object)null) { Build(); } open = !open; if (open) { canvasGo.SetActive(true); FitToCanvas(); UiTween.PanelOpened(); GildedUIModule.TypeNow(canvasGo); if (activeModule == null) { activeModule = PageOf(Options.ModuleOrder.FirstOrDefault()); } SetCollapsed(F7Catalog.Category(activeModule), v: false); BuildTabs(); ShowModule(activeModule); RefreshStatus(); } else { KeybindRow.Capturing = null; ShortcutRow.capturing = null; ForeignMods.FlushSaves(); UITooltip.HideTooltip(); } } private void LateUpdate() { if ((Object)(object)canvasGo == (Object)null || !canvasGo.activeSelf || (!typeDirty && !textRefit)) { return; } bool flag = textRefit; textRefit = false; if (!(typeDirty || flag)) { return; } typeDirty = false; if ((Object)(object)listContent != (Object)null) { GildedUIModule.TypeNow(((Component)listContent).gameObject); } if ((Object)(object)tabsContent != (Object)null) { GildedUIModule.TypeNow(((Component)tabsContent).gameObject); } RectTransform val = (RectTransform)(((Object)(object)listContent != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { FlowJump(val); } if (!((Object)(object)listContent != (Object)null)) { return; } ((Component)listContent).GetComponentsInChildren<RowFit>(true, fitBuf); foreach (RowFit item in fitBuf) { if ((Object)(object)item != (Object)null) { item.Refit(); } } fitBuf.Clear(); LayoutRebuilder.MarkLayoutForRebuild(listContent); } public static void TextChanged() { textRefit = true; } private static void CloseGlyph(RectTransform close) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) Sprite val = (Gilded.Pref ? Gilded.Load("g3_close_64", 0f, 100f, mips: true) : null); Sprite val2 = (((Object)(object)val != (Object)null) ? Gilded.Load("g3_close_hover_64", 0f, 100f, mips: true) : null); if ((Object)(object)val != (Object)null) { RectTransform obj = Theme.Rect("XGlyph", (Transform)(object)close); Theme.Place(obj, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(24f, 24f)); Image val3 = Theme.Img((Component)(object)obj, val, Color.white, sliced: false, raycast: false); ((Graphic)val3).raycastTarget = false; val3.preserveAspect = true; CloseHover closeHover = ((Component)close).gameObject.AddComponent<CloseHover>(); closeHover.Img = val3; closeHover.Normal = val; closeHover.Hover = val2 ?? val; } else { for (int i = 0; i < 2; i++) { RectTransform obj2 = Theme.Rect("X" + i, (Transform)(object)close); Theme.P