using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MTSeedExplorer.Automation; using MTSeedExplorer.Core; using MTSeedExplorer.HarmonyPatches; using MTSeedExplorer.UI; using Microsoft.CodeAnalysis; using ShinyShoe; using ShinyShoe.Loading; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MTSeedExplorer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+56e1e43aaaeb42c2b865014c71a1a53b084d054c")] [assembly: AssemblyProduct("MTSeedExplorer")] [assembly: AssemblyTitle("MTSeedExplorer")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } public static class CellAlignment { private static void Align(GameObject cell, TextAnchor anchor) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) HorizontalLayoutGroup component = cell.GetComponent(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } VerticalLayoutGroup component2 = cell.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } GridLayoutGroup component3 = cell.GetComponent(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3); } HorizontalLayoutGroup val = cell.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val).spacing = 0f; ((LayoutGroup)val).padding = new RectOffset(0, 0, 0, 0); ((LayoutGroup)val).childAlignment = anchor; } public static void AlignTopLeft(GameObject cell) { Align(cell, (TextAnchor)0); } public static void AlignTopCenter(GameObject cell) { Align(cell, (TextAnchor)1); } public static void AlignTopRight(GameObject cell) { Align(cell, (TextAnchor)2); } public static void AlignMiddleLeft(GameObject cell) { Align(cell, (TextAnchor)3); } public static void AlignMiddleCenter(GameObject cell) { Align(cell, (TextAnchor)4); } public static void AlignMiddleRight(GameObject cell) { Align(cell, (TextAnchor)5); } public static void AlignBottomLeft(GameObject cell) { Align(cell, (TextAnchor)6); } public static void AlignBottomCenter(GameObject cell) { Align(cell, (TextAnchor)7); } public static void AlignBottomRight(GameObject cell) { Align(cell, (TextAnchor)8); } } namespace MTSeedExplorer { [HarmonyPatch(typeof(RelicManager))] public static class RelicManagerPatches { } [BepInPlugin("MTSeedExplorer_628343be-325d-44b9-9d11-13f7934974ab", "MTSeedExplorer", "1.0.2")] public class Plugin : BaseUnityPlugin { internal sealed class PreloadDriver : MonoBehaviour { private void Update() { DriveSeedPreload(); AutomationBridge.DrainActiveMainThreadQueue(); } } internal static ManualLogSource Logger; private static AutomationBridge automationBridge; private static RunSetupScreen activeRunSetupScreen; private static string lastObservedSignature; private static int signatureStableFrames; private const int signatureStableFrameThreshold = 1; private const int seedsPerUpdate = 4; internal static bool IsRunSetupScreenActive => (Object)(object)activeRunSetupScreen != (Object)null && (Object)(object)((Component)activeRunSetupScreen).gameObject != (Object)null && ((Component)activeRunSetupScreen).gameObject.activeInHierarchy; internal static void Log(string message) { Logger.LogInfo((object)message); } internal static void LogError(string message) { Logger.LogError((object)message); } internal static void NotifyRunSetupScreenActive(RunSetupScreen screen) { activeRunSetupScreen = screen; lastObservedSignature = null; signatureStableFrames = 0; if ((Object)(object)screen != (Object)null && (Object)(object)((Component)screen).GetComponent() == (Object)null) { ((Component)screen).gameObject.AddComponent(); Log("PreloadDriver attached to RunSetupScreen; preload poller armed."); } else { Log("RunSetupScreen activated; preload poller already armed."); } } private void Awake() { Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Logger = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "MTSeedExplorer_628343be-325d-44b9-9d11-13f7934974ab"); Settings.Init(((BaseUnityPlugin)this).Config); if (automationBridge == null) { automationBridge = AutomationBridge.TryStart(); } } private void Update() { automationBridge?.DrainMainThreadQueue(); DriveSeedPreload(); } private static void DriveSeedPreload() { if ((Object)(object)activeRunSetupScreen == (Object)null || (Object)(object)((Component)activeRunSetupScreen).gameObject == (Object)null || !((Component)activeRunSetupScreen).gameObject.activeInHierarchy) { return; } RunSetupContext runSetupContext = RunSetupContext.TryCapture(activeRunSetupScreen); if (runSetupContext == null) { return; } if (runSetupContext.Signature != lastObservedSignature) { lastObservedSignature = runSetupContext.Signature; signatureStableFrames = 0; return; } if (signatureStableFrames < 1) { signatureStableFrames++; if (signatureStableFrames < 1) { return; } } SeedExplorer orCreateInstance = SeedExplorer.GetOrCreateInstance(runSetupContext.Signature); if (orCreateInstance.PreloadContext == null || orCreateInstance.PreloadContext.Signature != runSetupContext.Signature) { Log("Beginning preload for context signature: " + runSetupContext.Signature); orCreateInstance.BeginPreload(runSetupContext, Math.Max(1, Settings.InitialSeedCount.Value)); } for (int i = 0; i < 4; i++) { SeedExplorer.PreloadStatus status = orCreateInstance.Status; orCreateInstance.Tick(); if (status != orCreateInstance.Status) { Log($"Preload status: {status} -> {orCreateInstance.Status} (results: {orCreateInstance.SeedResults.Count}/{orCreateInstance.TargetSeedCount})"); } if (orCreateInstance.Status != SeedExplorer.PreloadStatus.Generating && orCreateInstance.Status != SeedExplorer.PreloadStatus.Populating) { break; } } } private void OnDestroy() { ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)"MTSeedExplorer plugin object destroyed."); } } } public static class PluginInfo { public const string PLUGIN_GUID = "MTSeedExplorer_628343be-325d-44b9-9d11-13f7934974ab"; public const string PLUGIN_NAME = "MTSeedExplorer"; public const string PLUGIN_VERSION = "1.0.2"; } public static class Settings { public static ConfigEntry SearchTimeoutSeconds; public static ConfigEntry InitialSeedCount; public static ConfigEntry EnableDebugLogging; public static ConfigEntry EnableAutomationBridge; public static ConfigEntry AutomationBridgePort; public static ConfigEntry AutomationArtifactDirectory; public static void Init(ConfigFile config) { SearchTimeoutSeconds = config.Bind("General", "SearchTimeoutSeconds", 60, "How long to search for a seed when given a filter."); InitialSeedCount = config.Bind("General", "InitialSeedCount", 13, "How many seeds to display when first opening the mod."); EnableDebugLogging = config.Bind("General", "EnableDebugLogging", false, "Write debug logs to the console."); EnableAutomationBridge = config.Bind("Automation", "EnableAutomationBridge", false, "Enable the localhost-only debug automation bridge for UI smoke tests."); AutomationBridgePort = config.Bind("Automation", "AutomationBridgePort", 59221, "Local TCP port used by the debug automation bridge."); AutomationArtifactDirectory = config.Bind("Automation", "AutomationArtifactDirectory", "", "Directory where automation bridge screenshots should be written. Empty uses the current working directory."); } } } namespace MTSeedExplorer.UI { internal sealed class ScrollEventForwarder : MonoBehaviour, IScrollHandler, IEventSystemHandler { public void OnScroll(PointerEventData eventData) { Transform parent = ((Component)this).transform.parent; if (!((Object)(object)parent == (Object)null)) { ExecuteEvents.ExecuteHierarchy(((Component)parent).gameObject, (BaseEventData)(object)eventData, ExecuteEvents.scrollHandler); } } } internal static class SeedExplorerCardPreviewPrefabs { internal enum RelicPreviewRole { Artifact, Enhancer, Any } private static CardUI cachedCardPrefab; private static string cachedCardSource; private static readonly Dictionary cachedRelicPrefabs = new Dictionary(); private static readonly Dictionary cachedRelicSources = new Dictionary(); private static bool artifactBackgroundPreloadStarted; private static bool artifactBackgroundPreloadCompleted; private static readonly List attemptLog = new List(); internal static IReadOnlyList AttemptLog => attemptLog; internal static bool IsArtifactBackgroundPreloadStarted => artifactBackgroundPreloadStarted; internal static bool IsArtifactBackgroundPreloadCompleted => artifactBackgroundPreloadCompleted; internal static bool IsArtifactBackgroundPreloadInProgress => artifactBackgroundPreloadStarted && !artifactBackgroundPreloadCompleted; internal static bool TryGetCardPrefab(out CardUI prefab, out string source) { if ((Object)(object)cachedCardPrefab != (Object)null) { prefab = cachedCardPrefab; source = cachedCardSource ?? ""; return true; } CardUI val = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType: " + (((Object)(object)val != (Object)null) ? "found" : "null")); if ((Object)(object)val != (Object)null) { cachedCardPrefab = val; cachedCardSource = "FindObjectOfType"; prefab = val; source = cachedCardSource; return true; } RewardDetailsUI val2 = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType: " + (((Object)(object)val2 != (Object)null) ? "found" : "null")); if ((Object)(object)val2 != (Object)null) { CardUI val3 = ReflectField((object)val2, "cardUI"); attemptLog.Add("RewardDetailsUI.cardUI: " + (((Object)(object)val3 != (Object)null) ? "found" : "null")); if ((Object)(object)val3 != (Object)null) { cachedCardPrefab = val3; cachedCardSource = "RewardDetailsUI.cardUI"; prefab = val3; source = cachedCardSource; return true; } } CompendiumSectionCards val4 = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType: " + (((Object)(object)val4 != (Object)null) ? "found" : "null")); if ((Object)(object)val4 != (Object)null) { CardUI val5 = ReflectField((object)val4, "cardPrefab"); attemptLog.Add("CompendiumSectionCards.cardPrefab: " + (((Object)(object)val5 != (Object)null) ? "found" : "null")); if ((Object)(object)val5 != (Object)null) { cachedCardPrefab = val5; cachedCardSource = "CompendiumSectionCards.cardPrefab"; prefab = val5; source = cachedCardSource; return true; } } CardUI[] array = Resources.FindObjectsOfTypeAll(); attemptLog.Add("Resources.FindObjectsOfTypeAll: count=" + array.Length); CardUI[] array2 = array; foreach (CardUI val6 in array2) { if (!((Object)(object)val6 == (Object)null)) { cachedCardPrefab = val6; cachedCardSource = "Resources.FindObjectsOfTypeAll"; prefab = val6; source = cachedCardSource; return true; } } prefab = null; source = ""; return false; } internal static bool TryGetRelicPrefab(out RelicInfoUI prefab, out string source) { return TryGetRelicPrefab(RelicPreviewRole.Any, out prefab, out source); } internal static bool TryGetRelicPrefab(RelicPreviewRole role, out RelicInfoUI prefab, out string source) { string key = role.ToString(); if (cachedRelicPrefabs.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { prefab = value; source = (cachedRelicSources.TryGetValue(key, out var value2) ? value2 : ""); return true; } if (role == RelicPreviewRole.Artifact && TryGetRelicDraftPrefab(out var prefab2, out var source2)) { return CacheRelicPrefab(role, prefab2, source2, out prefab, out source); } RewardDetailsUI val = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType for RelicInfoUI: " + (((Object)(object)val != (Object)null) ? "found" : "null")); if ((Object)(object)val != (Object)null) { string[] relicFieldPreference = GetRelicFieldPreference(role); foreach (string text in relicFieldPreference) { RelicInfoUI val2 = ReflectField((object)val, text); attemptLog.Add("RewardDetailsUI." + text + ": " + (((Object)(object)val2 != (Object)null) ? "found" : "null")); if ((Object)(object)val2 != (Object)null) { return CacheRelicPrefab(role, val2, "RewardDetailsUI." + text, out prefab, out source); } } } RelicInfoUI val3 = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType: " + (((Object)(object)val3 != (Object)null) ? "found" : "null")); if ((Object)(object)val3 != (Object)null) { return CacheRelicPrefab(role, val3, "FindObjectOfType", out prefab, out source); } RelicInfoUI[] array = Resources.FindObjectsOfTypeAll(); attemptLog.Add("Resources.FindObjectsOfTypeAll: count=" + array.Length); RelicInfoUI[] array2 = array; foreach (RelicInfoUI val4 in array2) { if (!((Object)(object)val4 == (Object)null)) { return CacheRelicPrefab(role, val4, "Resources.FindObjectsOfTypeAll", out prefab, out source); } } prefab = null; source = ""; return false; } private static bool TryGetRelicDraftPrefab(out RelicInfoUI prefab, out string source) { RelicDraftScreen[] array = Resources.FindObjectsOfTypeAll(); attemptLog.Add("Resources.FindObjectsOfTypeAll: count=" + array.Length); RelicDraftScreen[] array2 = array; foreach (RelicDraftScreen val in array2) { if ((Object)(object)val == (Object)null) { continue; } LayoutGroupReplacementElement val2 = ReflectField((object)val, "itemLayout"); attemptLog.Add("RelicDraftScreen.itemLayout: " + (((Object)(object)val2 != (Object)null) ? "found" : "null")); if (!((Object)(object)val2 == (Object)null)) { RelicInfoUI componentInChildren = ((Component)val2).GetComponentInChildren(true); attemptLog.Add("RelicDraftScreen.itemLayout RelicInfoUI: " + (((Object)(object)componentInChildren != (Object)null) ? "found" : "null")); if ((Object)(object)componentInChildren != (Object)null) { prefab = componentInChildren; source = "RelicDraftScreen.itemLayout RelicInfoUI"; return true; } } } prefab = null; source = ""; return false; } internal static bool TryGetCardDraftBgItemPrefab(out CardDraftBgItem prefab, out string source) { CardDraftBgItem val = Object.FindObjectOfType(true); attemptLog.Add("FindObjectOfType: " + (((Object)(object)val != (Object)null) ? "found" : "null")); if ((Object)(object)val != (Object)null) { prefab = val; source = "FindObjectOfType"; return true; } CardDraftBgItem[] array = Resources.FindObjectsOfTypeAll(); attemptLog.Add("Resources.FindObjectsOfTypeAll: count=" + array.Length); CardDraftBgItem[] array2 = array; foreach (CardDraftBgItem val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { prefab = val2; source = "Resources.FindObjectsOfTypeAll"; return true; } } prefab = null; source = ""; return false; } internal static void PreloadArtifactBackgroundTemplates() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (artifactBackgroundPreloadCompleted || artifactBackgroundPreloadStarted) { return; } if (Resources.FindObjectsOfTypeAll().Length != 0) { artifactBackgroundPreloadStarted = true; artifactBackgroundPreloadCompleted = true; return; } try { artifactBackgroundPreloadStarted = true; LoadingScreen.AddTask((LoadingTask)new PreloadAdditiveScreen((ScreenName)4, (Action)delegate { artifactBackgroundPreloadCompleted = true; }), true); } catch (Exception ex) { attemptLog.Add("PreloadAdditiveScreen(RelicChoice) failed: " + ex.Message); Plugin.LogError("Artifact background template preload failed: " + ex); artifactBackgroundPreloadCompleted = true; } } private static string[] GetRelicFieldPreference(RelicPreviewRole role) { return role switch { RelicPreviewRole.Enhancer => new string[4] { "upgradeUI", "relicUI", "sinRelicUI", "mutatorUI" }, RelicPreviewRole.Artifact => new string[4] { "relicUI", "upgradeUI", "sinRelicUI", "mutatorUI" }, _ => new string[4] { "relicUI", "upgradeUI", "sinRelicUI", "mutatorUI" }, }; } private static bool CacheRelicPrefab(RelicPreviewRole role, RelicInfoUI value, string valueSource, out RelicInfoUI prefab, out string source) { string key = role.ToString(); cachedRelicPrefabs[key] = value; cachedRelicSources[key] = valueSource; prefab = value; source = valueSource; return true; } private static T ReflectField(object target, string fieldName) where T : Object { if (target == null) { return default(T); } try { FieldInfo field = target.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return default(T); } object value = field.GetValue(target); return (T)((value is T) ? value : null); } catch (Exception ex) { attemptLog.Add("Reflection failed on " + fieldName + ": " + ex.Message); return default(T); } } } public class SeedExplorerDialog : MonoBehaviour { internal sealed class DropdownAutomationState { internal string Id { get; } internal bool Present { get; } internal bool Expanded { get; } internal int OptionCount { get; } internal int SelectedIndex { get; } internal string SelectedValue { get; } internal List Options { get; } internal DropdownAutomationState(string id, bool present, bool expanded, int optionCount, int selectedIndex, string selectedValue, List options) { Id = id; Present = present; Expanded = expanded; OptionCount = optionCount; SelectedIndex = selectedIndex; SelectedValue = selectedValue; Options = options; } } internal sealed class ResultRowAutomationState { internal int Index { get; } internal SeedExplorer.SeedResult Result { get; } internal ResultRowAutomationState(int index, SeedExplorer.SeedResult result) { Index = index; Result = result; } } internal sealed class ScrollAutomationState { internal float VerticalNormalizedPosition; internal int RowCount; internal float ContentHeight; internal float ViewportHeight; internal float ScrollableHeight; } internal sealed class ResultCellClickAutomationState { internal int RowIndex; internal string Column; internal string TargetObjectName; internal string HandlerObjectName; internal bool DialogOpen; internal int? ChosenSeed; } private GameUISelectableDropdown Card1Dropdown; private GameUISelectableDropdown Card2Dropdown; private GameUISelectableDropdown Card3Dropdown; private GameUISelectableDropdown ArtifactDropdown; private GameUISelectableDropdown UpgradeDropdown; private Transform dropdownRow; private RectTransform contentRT; private SeedExplorer seedExplorer; private ScreenDialog dialog; internal ScrollRect scrollRect; private TextMeshProUGUI title; private TextMeshProUGUI warning; private TextMeshProUGUI dialogChosenSeedLabel; private SeedExplorerHoverPreview hoverPreview; private bool isInitialized = false; private bool _userOpened; private long lastRenderedPreloadVersion = -1L; private bool dropdownsBuilt; private readonly Dictionary automationDropdowns = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary> automationDropdownOptions = new Dictionary>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary automationDropdownSelectedIndexes = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<(int row, string columnId), (string text, SeedExplorerHoverPreview.PreviewKind kind)> resultCellHoverRegistry = new Dictionary<(int, string), (string, SeedExplorerHoverPreview.PreviewKind)>(); private readonly Dictionary<(int row, string columnId), GameObject> resultCellLabelObjects = new Dictionary<(int, string), GameObject>(); public static SeedExplorerDialog Instantiate(RunSetupScreen runSetupScreen) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown MutatorSelectionDialog val = (MutatorSelectionDialog)AccessTools.Field(typeof(RunSetupScreen), "mutatorSelectionDialog").GetValue(runSetupScreen); GameObject val2 = Object.Instantiate(((Component)val).gameObject, ((Component)val).transform.parent.parent); Object.DestroyImmediate((Object)(object)val2.GetComponent()); SeedExplorerDialog seedExplorerDialog = val2.AddComponent(); seedExplorerDialog.dialog = val2.GetComponentInChildren(true); ((ScreenTransition)seedExplorerDialog.dialog).SetActive(false, val2, (Action)null, (Action)null); return seedExplorerDialog; } private void Awake() { Init(); } private void OnEnable() { } private void OnDisable() { Close(); } private void Update() { if (!((Object)(object)dialog == (Object)null) && ((Component)dialog).gameObject.activeInHierarchy && seedExplorer != null && seedExplorer.PreloadVersion != lastRenderedPreloadVersion) { lastRenderedPreloadVersion = seedExplorer.PreloadVersion; if (!dropdownsBuilt && seedExplorer.PrimaryCardPool.Count > 0) { RelabelDropdowns(); dropdownsBuilt = true; } BuildResultsTable(); } } public void Open(string key = "") { DoOpen(key); } private void DoOpen(string key) { //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) seedExplorer = SeedExplorer.GetOrCreateInstance(key); if (seedExplorer.PrimaryCardPool.Count == 0 || seedExplorer.SeedResults.Count == 0) { Plugin.Log($"Choose Seed clicked while preload status={seedExplorer.Status} pools={seedExplorer.PrimaryCardPool.Count} seeds={seedExplorer.SeedResults.Count}; finishing on main thread."); if (seedExplorer.PreloadContext == null) { seedExplorer.ExploreSeeds(); } else { while ((seedExplorer.PrimaryCardPool.Count == 0 || seedExplorer.SeedResults.Count == 0) && seedExplorer.Status != SeedExplorer.PreloadStatus.Faulted) { seedExplorer.Tick(); } } } ((ScreenTransition)dialog).SetActive(true, ((Component)this).gameObject, (Action)null, (Action)null); dropdownsBuilt = false; lastRenderedPreloadVersion = -1L; UpdateDialogChosenSeedLabel(); BuildResultsTable(); RelabelDropdowns(); dropdownsBuilt = true; lastRenderedPreloadVersion = seedExplorer.PreloadVersion; LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)dropdownRow).GetComponent()); GameUISelectableDropdown[] array = (GameUISelectableDropdown[])(object)new GameUISelectableDropdown[5] { Card1Dropdown, Card2Dropdown, Card3Dropdown, ArtifactDropdown, UpgradeDropdown }; GameUISelectableDropdown[] array2 = array; foreach (GameUISelectableDropdown val in array2) { Transform obj = ((Component)val).transform.Find("Value"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); if ((Object)(object)val2 != (Object)null) { val2.anchorMin = new Vector2(0f, 0f); val2.anchorMax = new Vector2(1f, 1f); val2.offsetMin = new Vector2(4f, val2.offsetMin.y); val2.offsetMax = new Vector2(-4f, val2.offsetMax.y); } } if ((Object)(object)scrollRect != (Object)null) { scrollRect.verticalNormalizedPosition = 1f; LayoutRebuilder.ForceRebuildLayoutImmediate(scrollRect.content); } } private static void MakeDropdownScrollable(GameUISelectableDropdown dd, float maxHeightPx) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) object? obj = typeof(GameUISelectableDropdown).GetField("dropdownList", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(dd); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val == (Object)null)) { RectTransform component = val.GetComponent(); Transform parent = val.transform.parent; Rect rect = component.rect; float num = Mathf.Min(((Rect)(ref rect)).height, maxHeightPx); GameObject val2 = new GameObject("DropdownViewport", new Type[4] { typeof(RectTransform), typeof(Image), typeof(Mask), typeof(ScrollRect) }); val2.transform.SetParent(parent, false); RectTransform component2 = val2.GetComponent(); component2.anchorMin = component.anchorMin; component2.anchorMax = component.anchorMax; component2.pivot = component.pivot; component2.anchoredPosition = component.anchoredPosition; component2.sizeDelta = new Vector2(component.sizeDelta.x, num); Image component3 = val2.GetComponent(); ((Graphic)component3).color = new Color(1f, 1f, 1f, 0f); Mask component4 = val2.GetComponent(); component4.showMaskGraphic = false; val.transform.SetParent(val2.transform, false); RectTransform component5 = val.GetComponent(); component5.anchorMin = new Vector2(0f, 1f); component5.anchorMax = new Vector2(1f, 1f); component5.pivot = new Vector2(0.5f, 1f); component5.anchoredPosition = Vector2.zero; ScrollRect component6 = val2.GetComponent(); component6.content = component5; component6.viewport = component2; component6.horizontal = false; component6.vertical = true; component6.scrollSensitivity = 20f; ScrollRect componentInChildren = ((Component)((Component)dd).transform.root).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.verticalScrollbar != (Object)null) { GameObject val3 = Object.Instantiate(((Component)componentInChildren.verticalScrollbar).gameObject, val2.transform, false); Scrollbar component7 = val3.GetComponent(); component6.verticalScrollbar = component7; component6.verticalScrollbarVisibility = (ScrollbarVisibility)1; } val2.transform.SetSiblingIndex(parent.childCount - 1); LayoutRebuilder.ForceRebuildLayoutImmediate(component2); } } private void Init() { if (!isInitialized) { isInitialized = true; scrollRect = ((Component)dialog).GetComponentInChildren(true); ((Component)scrollRect).transform.SetParent((Transform)null, false); SetupDialogHeader(); SetupDialogBody(); RectTransform component = ((Component)((Component)dialog).transform.Find("Content")).GetComponent(); if (hoverPreview == null) { hoverPreview = new SeedExplorerHoverPreview(((Component)dialog).transform); } SeedExplorerHoverPreview.PreloadCardArt(); SeedExplorerCardPreviewPrefabs.PreloadArtifactBackgroundTemplates(); LayoutRebuilder.ForceRebuildLayoutImmediate(component); } } private void SetupDialogBody() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0087: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)dialog).transform.Find("Content"); GameObject val2 = new GameObject("Body", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val, false); LayoutElement val3 = val2.AddComponent(); val3.flexibleHeight = 1f; val3.minHeight = 0f; ((Component)scrollRect).transform.SetParent(val2.transform, false); RectTransform component = ((Component)scrollRect).GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; scrollRect.vertical = true; scrollRect.horizontal = false; scrollRect.scrollSensitivity = 30f; RectTransform viewport = scrollRect.viewport; ((Object)((Component)viewport).gameObject).name = SeedExplorerUiAutomationIds.ResultsViewportObjectName; if ((Object)(object)((Component)viewport).gameObject.GetComponent() == (Object)null) { ((Component)viewport).gameObject.AddComponent(); } contentRT = ((Component)((Transform)viewport).Find("Mutator layout")).GetComponent(); scrollRect.content = contentRT; contentRT.anchorMin = new Vector2(0f, 1f); contentRT.anchorMax = new Vector2(1f, 1f); contentRT.pivot = new Vector2(0.5f, 1f); contentRT.anchoredPosition = Vector2.zero; contentRT.sizeDelta = Vector2.zero; LayoutGroup[] components = ((Component)contentRT).GetComponents(); foreach (LayoutGroup val4 in components) { Object.DestroyImmediate((Object)(object)val4); } VerticalLayoutGroup val5 = ((Component)contentRT).gameObject.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val5).spacing = 1f; ((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false; ContentSizeFitter val6 = ((Component)contentRT).GetComponent() ?? ((Component)contentRT).gameObject.AddComponent(); val6.horizontalFit = (FitMode)0; val6.verticalFit = (FitMode)2; LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)dialog).GetComponentInChildren(true).content); } private void BuildResultsTable() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Expected O, but got Unknown //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Expected O, but got Unknown List list = new List(); foreach (Transform item2 in (Transform)contentRT) { Transform item = item2; list.Add(item); } foreach (Transform item3 in list) { Object.DestroyImmediate((Object)(object)((Component)item3).gameObject); } resultCellHoverRegistry.Clear(); resultCellLabelObjects.Clear(); Color val2 = default(Color); for (int i = 0; i < seedExplorer.SeedResultsFiltered.Count; i++) { SeedExplorer.SeedResult seedResult = seedExplorer.SeedResultsFiltered[i]; string[] array = new string[3] { seedResult.Card1, seedResult.Card2, seedResult.Card3 }; GameObject val = new GameObject(SeedExplorerUiAutomationIds.ResultRowObjectName(i), new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)contentRT, false); Image bg = val.AddComponent(); bool flag = seedExplorer.SelectedSeedResult != null && seedResult.Seed == seedExplorer.SelectedSeedResult.Seed; ((Color)(ref val2))..ctor(1f, 0.8f, 0.4f, 0.25f); Color hoverColor = new Color(1f, 1f, 1f, 0.2f); Color val3 = (flag ? val2 : Color.clear); ((Graphic)bg).color = val3; val.AddComponent(); EventTrigger val4 = val.AddComponent(); Color restColorCaptured = val3; Entry val5 = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent)(object)val5.callback).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ((Graphic)bg).color = hoverColor; }); val4.triggers.Add(val5); Entry val6 = new Entry { eventID = (EventTriggerType)1 }; ((UnityEvent)(object)val6.callback).AddListener((UnityAction)delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ((Graphic)bg).color = restColorCaptured; }); val4.triggers.Add(val6); int rowIndex = i; Entry val7 = new Entry { eventID = (EventTriggerType)4 }; ((UnityEvent)(object)val7.callback).AddListener((UnityAction)delegate { SelectResultRowForRun(rowIndex); }); val4.triggers.Add(val7); ContentSizeFitter val8 = val.AddComponent(); val8.horizontalFit = (FitMode)0; val8.verticalFit = (FitMode)2; HorizontalLayoutGroup val9 = val.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val9).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)val9).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val9).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandHeight = false; ((LayoutGroup)val9).childAlignment = (TextAnchor)4; string[] array2 = new string[3] { "primary", "secondary", "unit" }; SeedExplorerHoverPreview.PreviewKind[] array3 = new SeedExplorerHoverPreview.PreviewKind[3] { SeedExplorerHoverPreview.PreviewKind.PrimaryCard, SeedExplorerHoverPreview.PreviewKind.SecondaryCard, SeedExplorerHoverPreview.PreviewKind.UnitCard }; for (int j = 0; j < 3; j++) { GameObject val10 = new GameObject($"Cell_{j + 1}", new Type[1] { typeof(RectTransform) }); val10.transform.SetParent(val.transform, false); LayoutElement val11 = val10.AddComponent(); val11.flexibleWidth = 1f; val11.minWidth = 0f; string text = ((j < array.Length) ? array[j] : ""); TextMeshProUGUI val12 = CreateResultCellLabel(val10.transform, rowIndex, array2[j], text, array3[j]); LayoutRebuilder.ForceRebuildLayoutImmediate(((TMP_Text)val12).rectTransform); val11.minHeight = 30f; val11.preferredHeight = 30f; } float num = 61f; GameObject val13 = new GameObject("ArtifactCell", new Type[1] { typeof(RectTransform) }); val13.transform.SetParent(val.transform, false); LayoutElement val14 = val13.AddComponent(); val14.flexibleWidth = 1f; val14.minWidth = 0f; val14.minHeight = num; val14.preferredHeight = num; VerticalLayoutGroup val15 = val13.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val15).spacing = 1f; ((HorizontalOrVerticalLayoutGroup)val15).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val15).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val15).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val15).childForceExpandHeight = false; ContentSizeFitter val16 = val13.AddComponent(); val16.horizontalFit = (FitMode)0; val16.verticalFit = (FitMode)2; string[] array4 = new string[2] { "artifact1", "artifact2" }; string[] array5 = new string[2] { seedResult.Artifact1, seedResult.Artifact2 }; for (int k = 0; k < array5.Length; k++) { CreateResultCellLabel(val13.transform, rowIndex, array4[k], array5[k], SeedExplorerHoverPreview.PreviewKind.Artifact); } GameObject val17 = new GameObject("UpgradeCell", new Type[1] { typeof(RectTransform) }); val17.transform.SetParent(val.transform, false); LayoutElement val18 = val17.AddComponent(); val18.flexibleWidth = 1f; val18.minWidth = 0f; val18.minHeight = num; val18.preferredHeight = num; VerticalLayoutGroup val19 = val17.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val19).spacing = 1f; ((HorizontalOrVerticalLayoutGroup)val19).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val19).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val19).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val19).childForceExpandHeight = false; ContentSizeFitter val20 = val17.AddComponent(); val20.horizontalFit = (FitMode)0; val20.verticalFit = (FitMode)2; string[] array6 = new string[2] { "upgrade1", "upgrade2" }; string[] array7 = new string[2] { seedResult.Upgrade1, seedResult.Upgrade2 }; for (int l = 0; l < array7.Length; l++) { CreateResultCellLabel(val17.transform, rowIndex, array6[l], array7[l], SeedExplorerHoverPreview.PreviewKind.ChampionUpgrade); } } } private TextMeshProUGUI CreateResultCellLabel(Transform parent, int rowIndex, string columnId, string text, SeedExplorerHoverPreview.PreviewKind kind) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0145: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown string text2 = SeedExplorerUiAutomationIds.NormalizeResultColumnId(columnId); GameObject val = new GameObject(SeedExplorerUiAutomationIds.ResultCellLabelObjectName(rowIndex, text2), new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text ?? ""; ((TMP_Text)val2).fontSize = 20f; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((Graphic)val2).raycastTarget = true; ContentSizeFitter val3 = val.AddComponent(); val3.horizontalFit = (FitMode)2; val3.verticalFit = (FitMode)2; resultCellHoverRegistry[(rowIndex, text2)] = (((TMP_Text)val2).text, kind); resultCellLabelObjects[(rowIndex, text2)] = val; val.AddComponent(); if (!string.IsNullOrEmpty(((TMP_Text)val2).text)) { EventTrigger val4 = val.AddComponent(); string capturedText = ((TMP_Text)val2).text; SeedExplorerHoverPreview.PreviewKind capturedKind = kind; int capturedRowIndex = rowIndex; Entry val5 = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent)(object)val5.callback).AddListener((UnityAction)delegate { if (hoverPreview != null) { hoverPreview.Show(capturedKind, capturedText); } }); val4.triggers.Add(val5); Entry val6 = new Entry { eventID = (EventTriggerType)1 }; ((UnityEvent)(object)val6.callback).AddListener((UnityAction)delegate { if (hoverPreview != null) { hoverPreview.Hide(); } }); val4.triggers.Add(val6); Entry val7 = new Entry { eventID = (EventTriggerType)4 }; ((UnityEvent)(object)val7.callback).AddListener((UnityAction)delegate { SelectResultRowForRun(capturedRowIndex); }); val4.triggers.Add(val7); } return val2; } private void SetupDialogHeader() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_02a3: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Expected O, but got Unknown Transform val = ((Component)dialog).transform.Find("Content"); Object.DestroyImmediate((Object)(object)((Component)val).GetComponent()); Object.DestroyImmediate((Object)(object)((Component)val).GetComponent()); List list = new List(); foreach (Transform item2 in val) { Transform item = item2; list.Add(item); } foreach (Transform item3 in list) { Object.DestroyImmediate((Object)(object)((Component)item3).gameObject); } VerticalLayoutGroup val2 = ((Component)val).gameObject.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 0f; ((LayoutGroup)val2).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; RectTransform component = ((Component)val).GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = Vector2.zero; component.sizeDelta = Vector2.zero; GameObject val3 = new GameObject("Header", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(((Component)val).transform, false); RectTransform component2 = val3.GetComponent(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(1f, 1f); component2.pivot = new Vector2(0.5f, 1f); component2.anchoredPosition = Vector2.zero; component2.sizeDelta = Vector2.zero; VerticalLayoutGroup val4 = val3.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val4).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)val4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val4).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = false; ContentSizeFitter val5 = val3.AddComponent(); val5.horizontalFit = (FitMode)0; val5.verticalFit = (FitMode)2; int[] array = new int[3] { 2, 5, 5 }; List list2 = new List(); for (int i = 0; i < 3; i++) { List list3 = new List(); GameObject val6 = new GameObject($"Row{i + 1}", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(val3.transform, false); ContentSizeFitter val7 = val6.AddComponent(); val7.horizontalFit = (FitMode)0; val7.verticalFit = (FitMode)2; HorizontalLayoutGroup val8 = val6.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val8).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)val8).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val8).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val8).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val8).childForceExpandHeight = false; ((LayoutGroup)val8).childAlignment = (TextAnchor)4; for (int j = 0; j < array[i]; j++) { GameObject val9 = new GameObject($"Cell{i + 1}_{j + 1}", new Type[1] { typeof(RectTransform) }); val9.transform.SetParent(val6.transform, false); LayoutElement val10 = val9.AddComponent(); val10.flexibleWidth = 1f; val10.minWidth = 0f; list3.Add(val9.transform); } list2.Add(val6.transform); } SetupInstructionsAndToggle(((IEnumerable)list2[0]).Cast().ToList()); SetupDropdownTitles(((IEnumerable)list2[1]).Cast().ToList()); dropdownRow = list2[2]; SetupDropdowns(dropdownRow); component2 = val3.GetComponent(); LayoutRebuilder.ForceRebuildLayoutImmediate(component2); LayoutElement val11 = val3.gameObject.AddComponent(); val11.preferredHeight = LayoutUtility.GetPreferredHeight(component2); val11.flexibleHeight = 0f; } private void SetupInstructionsAndToggle(List cells) { LabelCell(cells[0], "Choose starting seed."); dialogChosenSeedLabel = LabelCell(cells[1], "", SeedExplorerUiAutomationIds.DialogChosenSeedLabelObjectName); UpdateDialogChosenSeedLabel(); } private void UpdateDialogChosenSeedLabel() { if (!((Object)(object)dialogChosenSeedLabel == (Object)null)) { int? num = seedExplorer?.SelectedSeedResult?.Seed; ((TMP_Text)dialogChosenSeedLabel).text = (num.HasValue ? ("Currently chosen: " + num.Value.ToString("X8")) : ""); } } private void SetupToggle(Transform target) { SettingsDialog val = Object.FindObjectOfType(true); if ((Object)(object)val == (Object)null) { throw new Exception("Unable to find SettingsDialog"); } Transform val2 = ((Component)val).transform.Find("Content/Content/Audio Section/Background mute toggle/Background mute toggle input"); if ((Object)(object)val2 == (Object)null) { throw new Exception("Unable to find toggle button to copy."); } GameObject val3 = Object.Instantiate(((Component)val2).gameObject, target, false); ((Object)val3).name = ((Object)target).name + " toggle"; RectTransform component = val3.GetComponent(); } public void Close() { if (hoverPreview != null) { hoverPreview.Hide(); } ((ScreenTransition)dialog).SetActive(false, ((Component)this).gameObject, (Action)null, (Action)null); SoundManager.PlaySfxSignal.Dispatch("UI_Cancel"); ((Behaviour)this).enabled = false; isInitialized = false; } internal bool ApplyScreenInput(CoreInputControlMapping mapping, IGameUIComponent triggeredUI, Controls triggeredMappingID) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!((Component)this).gameObject.activeSelf) { return false; } if (triggeredUI == null && InputHelper.IsClickInput(triggeredMappingID, mapping)) { Close(); return true; } return true; } internal bool IsOpenForAutomation() { return (Object)(object)dialog != (Object)null && ((Component)dialog).gameObject.activeInHierarchy; } internal List GetDropdownAutomationStates() { return SeedExplorerUiAutomationIds.DropdownIds.Select(GetDropdownAutomationState).ToList(); } internal DropdownAutomationState GetDropdownAutomationState(string id) { id = NormalizeAutomationDropdownId(id); GameUISelectableDropdown dropdownForAutomation = GetDropdownForAutomation(id); GameObject val = (((Object)(object)dropdownForAutomation != (Object)null) ? GetDropdownList(dropdownForAutomation) : null); bool present = (Object)(object)dropdownForAutomation != (Object)null && ((Component)dropdownForAutomation).gameObject.activeInHierarchy; bool expanded = (Object)(object)val != (Object)null && val.activeInHierarchy; List dropdownOptionsForAutomation = GetDropdownOptionsForAutomation(id); int optionCount = ((dropdownOptionsForAutomation.Count > 0) ? dropdownOptionsForAutomation.Count : (((Object)(object)val != (Object)null) ? ((IEnumerable)val.transform).Cast().Count((Transform t) => ((Object)t).name.StartsWith("Dropdown entry", StringComparison.OrdinalIgnoreCase)) : 0)); int value; int num = (automationDropdownSelectedIndexes.TryGetValue(id, out value) ? value : (-1)); string selectedValue = ((num >= 0 && num < dropdownOptionsForAutomation.Count) ? dropdownOptionsForAutomation[num] : ""); return new DropdownAutomationState(id, present, expanded, optionCount, num, selectedValue, dropdownOptionsForAutomation); } internal DropdownAutomationState ClickDropdownForAutomation(string id) { id = NormalizeAutomationDropdownId(id); GameUISelectableDropdown dropdownForAutomation = GetDropdownForAutomation(id); if ((Object)(object)dropdownForAutomation == (Object)null) { throw new InvalidOperationException("Seed Explorer dropdown was not found: " + id); } CoreInputControlMapping val = null; if ((Object)(object)InputManager.Inst != (Object)null) { ((CoreInput)InputManager.Inst).TryGetSignaledInputMapping(MappingID.op_Implicit((Enum)(object)(Controls)19), ref val); } dropdownForAutomation.ApplyScreenInput(val, (IGameUIComponent)(object)dropdownForAutomation, (Controls)19); return GetDropdownAutomationState(id); } internal DropdownAutomationState SelectDropdownOptionForAutomation(string id, int? requestedIndex, string requestedValue) { id = NormalizeAutomationDropdownId(id); GameUISelectableDropdown dropdownForAutomation = GetDropdownForAutomation(id); if ((Object)(object)dropdownForAutomation == (Object)null) { throw new InvalidOperationException("Seed Explorer dropdown was not found: " + id); } List dropdownOptionsForAutomation = GetDropdownOptionsForAutomation(id); if (dropdownOptionsForAutomation.Count == 0) { throw new InvalidOperationException("Seed Explorer dropdown has no automation options: " + id); } int num; if (requestedIndex.HasValue) { num = requestedIndex.Value; } else { if (string.IsNullOrWhiteSpace(requestedValue)) { throw new InvalidOperationException("Dropdown selection requires either an index or value."); } num = dropdownOptionsForAutomation.FindIndex((string option) => string.Equals(option, requestedValue, StringComparison.Ordinal)); } if (num < 0 || num >= dropdownOptionsForAutomation.Count) { throw new ArgumentOutOfRangeException("requestedIndex", $"Dropdown option index {num} was outside the option range for {id}."); } string optionName = dropdownOptionsForAutomation[num]; dropdownForAutomation.SetIndex(num); ApplyDropdownSelection(id, GetFilterTypeForAutomation(id), num, optionName); return GetDropdownAutomationState(id); } internal List GetResultRowsForAutomation() { EnsureSeedExplorerForAutomation(); return seedExplorer.SeedResultsFiltered.Select((SeedExplorer.SeedResult result, int index) => new ResultRowAutomationState(index, result)).ToList(); } internal ResultRowAutomationState ClickResultRowForAutomation(int index) { EnsureSeedExplorerForAutomation(); SelectResultRowForRun(index); return new ResultRowAutomationState(index, seedExplorer.SeedResultsFiltered[index]); } internal ScrollAutomationState GetScrollStateForAutomation() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) ScrollAutomationState scrollAutomationState = new ScrollAutomationState { RowCount = (((Object)(object)contentRT != (Object)null) ? ((Transform)contentRT).childCount : 0) }; if ((Object)(object)scrollRect != (Object)null) { scrollAutomationState.VerticalNormalizedPosition = scrollRect.verticalNormalizedPosition; Rect rect; if ((Object)(object)scrollRect.viewport != (Object)null) { rect = scrollRect.viewport.rect; scrollAutomationState.ViewportHeight = ((Rect)(ref rect)).height; } if ((Object)(object)scrollRect.content != (Object)null) { rect = scrollRect.content.rect; scrollAutomationState.ContentHeight = ((Rect)(ref rect)).height; } scrollAutomationState.ScrollableHeight = Mathf.Max(0f, scrollAutomationState.ContentHeight - scrollAutomationState.ViewportHeight); } return scrollAutomationState; } internal ScrollAutomationState DispatchScrollForAutomation(int rowIndex, float delta) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown if ((Object)(object)scrollRect == (Object)null || (Object)(object)contentRT == (Object)null) { return GetScrollStateForAutomation(); } GameObject val = ((rowIndex >= 0 && rowIndex < ((Transform)contentRT).childCount) ? ((Component)((Transform)contentRT).GetChild(rowIndex)).gameObject : (((Object)(object)scrollRect.viewport != (Object)null) ? ((Component)scrollRect.viewport).gameObject : ((Component)scrollRect).gameObject)); PointerEventData val2 = new PointerEventData(EventSystem.current) { scrollDelta = new Vector2(0f, delta) }; ExecuteEvents.ExecuteHierarchy(val, (BaseEventData)(object)val2, ExecuteEvents.scrollHandler); if ((Object)(object)scrollRect.content != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate(scrollRect.content); } return GetScrollStateForAutomation(); } internal int GetHighlightedRowIndexForAutomation() { if (seedExplorer == null || seedExplorer.SelectedSeedResult == null) { return -1; } int seed = seedExplorer.SelectedSeedResult.Seed; for (int i = 0; i < seedExplorer.SeedResultsFiltered.Count; i++) { if (seedExplorer.SeedResultsFiltered[i].Seed == seed) { return i; } } return -1; } internal string GetDialogChosenSeedLabelText() { return ((Object)(object)dialogChosenSeedLabel != (Object)null) ? ((TMP_Text)dialogChosenSeedLabel).text : ""; } private void SelectResultRowForRun(int index) { EnsureSeedExplorerForAutomation(); if (index < 0 || index >= seedExplorer.SeedResultsFiltered.Count) { throw new ArgumentOutOfRangeException("index", $"Seed result index {index} was outside the filtered result range."); } seedExplorer.StartRun(index); SeedExplorerFooterButton.RefreshChosenSeedLabel(); UpdateDialogChosenSeedLabel(); BuildResultsTable(); } private void EnsureSeedExplorerForAutomation() { if (seedExplorer == null) { throw new InvalidOperationException("Seed Explorer has not been opened."); } } private GameUISelectableDropdown GetDropdownForAutomation(string id) { if (!SeedExplorerUiAutomationIds.IsDropdownId(id)) { return null; } if (automationDropdowns.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { return value; } string expectedName = SeedExplorerUiAutomationIds.DropdownObjectName(id); return ((IEnumerable)((Component)this).GetComponentsInChildren(true)).FirstOrDefault((Func)((GameUISelectableDropdown x) => string.Equals(((Object)x).name, expectedName, StringComparison.OrdinalIgnoreCase))); } private static string NormalizeAutomationDropdownId(string id) { return (id ?? "").Trim().ToLowerInvariant(); } private List GetDropdownOptionsForAutomation(string id) { id = NormalizeAutomationDropdownId(id); List value; return automationDropdownOptions.TryGetValue(id, out value) ? value.ToList() : new List(); } private void StoreDropdownOptionsForAutomation(string id, List options) { id = NormalizeAutomationDropdownId(id); automationDropdownOptions[id] = options.ToList(); UpdateAutomationDropdownSelection(id, 0, (options.Count > 0) ? options[0] : ""); } private void UpdateAutomationDropdownSelection(string id, int index, string optionName) { id = NormalizeAutomationDropdownId(id); if (index < 0 && automationDropdownOptions.TryGetValue(id, out var value)) { index = value.FindIndex((string option) => string.Equals(option, optionName, StringComparison.Ordinal)); } automationDropdownSelectedIndexes[id] = index; } private static SeedExplorer.FilterType GetFilterTypeForAutomation(string id) { id = NormalizeAutomationDropdownId(id); return id switch { "primarycard" => SeedExplorer.FilterType.PrimaryCard, "secondarycard" => SeedExplorer.FilterType.SecondaryCard, "unitcard" => SeedExplorer.FilterType.UnitCard, "artifact" => SeedExplorer.FilterType.Artifact, "upgrade" => SeedExplorer.FilterType.Upgrade, _ => throw new InvalidOperationException("Unknown Seed Explorer dropdown id: " + id), }; } private void SetupDropdownTitles(List cells) { LabelCell(cells[0], "Primary"); LabelCell(cells[1], "Secondary"); LabelCell(cells[2], "Unit"); LabelCell(cells[3], "Artifact"); LabelCell(cells[4], "Upgrade"); } private void LabelCell(Transform cell, string text) { LabelCell(cell, text, "Label"); } private TextMeshProUGUI LabelCell(Transform cell, string text, string objectName) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown GameObject val = new GameObject(objectName ?? "Label", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(cell, false); LayoutElement val2 = ((Component)cell).gameObject.AddComponent(); val2.flexibleWidth = 1f; val2.minWidth = 0f; TextMeshProUGUI val3 = val.AddComponent(); ((TMP_Text)val3).text = text; ((TMP_Text)val3).fontSize = 24f; ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ContentSizeFitter val4 = val.AddComponent(); val4.horizontalFit = (FitMode)2; val4.verticalFit = (FitMode)2; LayoutRebuilder.ForceRebuildLayoutImmediate(((TMP_Text)val3).rectTransform); float preferredHeight = LayoutUtility.GetPreferredHeight(((TMP_Text)val3).rectTransform); val2.minHeight = 30f; val2.preferredHeight = 30f; return val3; } private void DestroyAllChildren(Transform t) { IEnumerable enumerable = from x in ((Component)t).GetComponentsInChildren(true) where (Object)(object)x != (Object)(object)t select ((Component)x).gameObject; foreach (GameObject item in enumerable) { Object.DestroyImmediate((Object)(object)item); } } private void RelabelDropdowns() { LabelDropdown(Card1Dropdown, "primarycard", seedExplorer.PrimaryCardPool); LabelDropdown(Card2Dropdown, "secondarycard", seedExplorer.SecondaryCardPool); LabelDropdown(Card3Dropdown, "unitcard", seedExplorer.UnitCardPool); LabelDropdown(ArtifactDropdown, "artifact", seedExplorer.ArtifactPool); LabelDropdown(UpgradeDropdown, "upgrade", seedExplorer.UpgradePool); } private void SetupDropdowns(Transform row) { List list = ((IEnumerable)row).Cast().ToList(); automationDropdowns.Clear(); automationDropdownOptions.Clear(); automationDropdownSelectedIndexes.Clear(); foreach (Transform item in list) { DestroyAllChildren(item); LayoutElement val = ((Component)item).GetComponent() ?? ((Component)item).gameObject.AddComponent(); val.minHeight = 70f; val.preferredHeight = 70f; } Card1Dropdown = CreateDropdown(list[0], seedExplorer.PrimaryCardPool, "primarycard"); Card2Dropdown = CreateDropdown(list[1], seedExplorer.SecondaryCardPool, "secondarycard"); Card3Dropdown = CreateDropdown(list[2], seedExplorer.UnitCardPool, "unitcard"); ArtifactDropdown = CreateDropdown(list[3], seedExplorer.ArtifactPool, "artifact"); UpgradeDropdown = CreateDropdown(list[4], seedExplorer.UpgradePool, "upgrade"); RegisterAutomationDropdown("primarycard", Card1Dropdown); RegisterAutomationDropdown("secondarycard", Card2Dropdown); RegisterAutomationDropdown("unitcard", Card3Dropdown); RegisterAutomationDropdown("artifact", ArtifactDropdown); RegisterAutomationDropdown("upgrade", UpgradeDropdown); RelabelDropdowns(); SetupDropdownButtonListeners(Card1Dropdown); SetupDropdownButtonListeners(Card2Dropdown); SetupDropdownButtonListeners(Card3Dropdown); SetupDropdownButtonListeners(ArtifactDropdown); SetupDropdownButtonListeners(UpgradeDropdown); Card1Dropdown.optionChosenSignal.AddListener((Action)delegate(int index, string optionName) { ApplyDropdownSelection("primarycard", SeedExplorer.FilterType.PrimaryCard, index, optionName); }); Card2Dropdown.optionChosenSignal.AddListener((Action)delegate(int index, string optionName) { ApplyDropdownSelection("secondarycard", SeedExplorer.FilterType.SecondaryCard, index, optionName); }); Card3Dropdown.optionChosenSignal.AddListener((Action)delegate(int index, string optionName) { ApplyDropdownSelection("unitcard", SeedExplorer.FilterType.UnitCard, index, optionName); }); ArtifactDropdown.optionChosenSignal.AddListener((Action)delegate(int index, string optionName) { ApplyDropdownSelection("artifact", SeedExplorer.FilterType.Artifact, index, optionName); }); UpgradeDropdown.optionChosenSignal.AddListener((Action)delegate(int index, string optionName) { ApplyDropdownSelection("upgrade", SeedExplorer.FilterType.Upgrade, index, optionName); }); list.ForEach(delegate(Transform c) { ((Component)c).gameObject.SetActive(true); }); } private void ApplyDropdownSelection(string automationId, SeedExplorer.FilterType filterType, int index, string optionName) { automationId = NormalizeAutomationDropdownId(automationId); UpdateAutomationDropdownSelection(automationId, index, optionName); seedExplorer.UpdateFilter(filterType, optionName); BuildResultsTable(); ResetResultsScrollForAutomation(); } private void ResetResultsScrollForAutomation() { if (!((Object)(object)scrollRect == (Object)null)) { scrollRect.verticalNormalizedPosition = 1f; LayoutRebuilder.ForceRebuildLayoutImmediate(scrollRect.content); } } private static GameObject GetDropdownList(GameUISelectableDropdown dd) { object? obj = typeof(GameUISelectableDropdown).GetField("dropdownList", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(dd); return (GameObject)((obj is GameObject) ? obj : null); } private static void SetDropdownListAutomationName(GameUISelectableDropdown dd, string automationId) { GameObject dropdownList = GetDropdownList(dd); if ((Object)(object)dropdownList != (Object)null) { ((Object)dropdownList).name = SeedExplorerUiAutomationIds.DropdownListObjectName(automationId); } } private static void ShrinkDropdownEntries(GameUISelectableDropdown dd, float entryHeight) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown GameObject dropdownList = GetDropdownList(dd); if ((Object)(object)dropdownList == (Object)null) { return; } foreach (Transform item in dropdownList.transform) { Transform val = item; if (((Object)val).name.StartsWith("Dropdown entry")) { RectTransform component = ((Component)val).GetComponent(); component.SetSizeWithCurrentAnchors((Axis)1, entryHeight); LayoutElement val2 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); val2.minHeight = entryHeight; val2.preferredHeight = entryHeight; val2.flexibleHeight = 0f; } } } private static void ExpandDropdownEntryWidths(GameUISelectableDropdown dd) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_008f: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00d5: 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_00f3: Unknown result type (might be due to invalid IL or missing references) GameObject dropdownList = GetDropdownList(dd); if ((Object)(object)dropdownList == (Object)null) { return; } VerticalLayoutGroup component = dropdownList.GetComponent(); if ((Object)(object)component != (Object)null) { ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; } foreach (Transform item in dropdownList.transform) { Transform val = item; if (((Object)val).name.StartsWith("Dropdown entry")) { RectTransform component2 = ((Component)val).GetComponent(); component2.anchorMin = new Vector2(0f, component2.anchorMin.y); component2.anchorMax = new Vector2(1f, component2.anchorMax.y); component2.offsetMin = new Vector2(0f, component2.offsetMin.y); component2.offsetMax = new Vector2(0f, component2.offsetMax.y); LayoutElement val2 = ((Component)val).GetComponent() ?? ((Component)val).gameObject.AddComponent(); val2.minWidth = 0f; val2.flexibleWidth = 1f; } } LayoutRebuilder.ForceRebuildLayoutImmediate(dropdownList.GetComponent()); } private void DumpDropdownLayout(GameUISelectableDropdown dd) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0219: 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) RectTransform component = ((Component)dd).GetComponent(); LayoutElement component2 = ((Component)dd).GetComponent(); ContentSizeFitter component3 = ((Component)dd).GetComponent(); Debug.Log((object)("––– Dump root of " + ((Object)dd).name + " –––")); Debug.Log((object)$"RT anchors [{component.anchorMin} → {component.anchorMax}] offsets [{component.offsetMin} → {component.offsetMax}] sizeDelta {component.sizeDelta}"); Debug.Log((object)(((Object)(object)component2 != (Object)null) ? $"LE minW:{component2.minWidth}, prefW:{component2.preferredWidth}, flexW:{component2.flexibleWidth}" : "no root LE")); Debug.Log((object)(((Object)(object)component3 != (Object)null) ? $"CSF H:{component3.horizontalFit}, V:{component3.verticalFit}" : "no root CSF")); foreach (Transform item in ((Component)dd).transform) { Transform val = item; RectTransform component4 = ((Component)val).GetComponent(); LayoutElement component5 = ((Component)val).GetComponent(); ContentSizeFitter component6 = ((Component)val).GetComponent(); Debug.Log((object)(" • Child '" + ((Object)val).name + "'")); Debug.Log((object)$" RT anchors [{component4.anchorMin} → {component4.anchorMax}] offsets [{component4.offsetMin} → {component4.offsetMax}] sizeDelta {component4.sizeDelta}"); Debug.Log((object)(((Object)(object)component5 != (Object)null) ? $" LE minW:{component5.minWidth}, prefW:{component5.preferredWidth}, flexW:{component5.flexibleWidth}" : " no LE")); Debug.Log((object)(((Object)(object)component6 != (Object)null) ? $" CSF H:{component6.horizontalFit}, V:{component6.verticalFit}" : " no CSF")); } } private void DumpHierarchy(Transform t, string indent = "") { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) //IL_00c0: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown RectTransform component = ((Component)t).GetComponent(); LayoutElement component2 = ((Component)t).GetComponent(); ContentSizeFitter component3 = ((Component)t).GetComponent(); Debug.Log((object)($"{indent}{((Object)t).name} ─ anchors [{component.anchorMin}->{component.anchorMax}] " + $"offsets [{component.offsetMin}->{component.offsetMax}] sizeDelta {component.sizeDelta} " + (((Object)(object)component2 != (Object)null) ? $"LE(minW:{component2.minWidth},flexW:{component2.flexibleWidth}) " : "") + (((Object)(object)component3 != (Object)null) ? $"CSF(H:{component3.horizontalFit},V:{component3.verticalFit})" : ""))); foreach (Transform item in t) { Transform t2 = item; DumpHierarchy(t2, indent + " "); } } private void DumpFullDropdown(GameUISelectableDropdown dd) { FieldInfo field = typeof(GameUISelectableDropdown).GetField("dropdownList", BindingFlags.Instance | BindingFlags.NonPublic); object? value = field.GetValue(dd); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"dropdownList NULL"); return; } Debug.Log((object)("─── FULL HIERARCHY for " + ((Object)dd).name + ".dropdownList ───")); DumpHierarchy(val.transform); } private static void CloneScrollRectForDropdown(GameUISelectableDropdown dd, ScrollRect templateScrollRect) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) object? obj = typeof(GameUISelectableDropdown).GetField("dropdownList", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(dd); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val == (Object)null)) { GameObject val2 = Object.Instantiate(((Component)templateScrollRect).gameObject, val.transform.parent, false); ScrollRect component = val2.GetComponent(); if ((Object)(object)component.content != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)component.content).gameObject); } RectTransform viewport = component.viewport; val.transform.SetParent((Transform)(object)viewport, false); component.content = val.GetComponent(); RectTransform component2 = val.GetComponent(); float num = (float)Screen.height * 0.4f; Rect rect = component2.rect; component2.SetSizeWithCurrentAnchors((Axis)1, Mathf.Min(((Rect)(ref rect)).height, num)); LayoutRebuilder.ForceRebuildLayoutImmediate(component.content); } } private void LabelDropdown(GameUISelectableDropdown dropdown, string automationId, List options) { if ((Object)(object)dropdown == (Object)null) { throw new InvalidOperationException("Unable to label missing Seed Explorer dropdown: " + automationId); } ((Object)dropdown).name = SeedExplorerUiAutomationIds.DropdownObjectName(automationId); List list = options.OrderBy((string x) => x).Prepend("").ToList(); StoreDropdownOptionsForAutomation(automationId, list); dropdown.SetOptions(list); SetDropdownListAutomationName(dropdown, automationId); TextMeshProUGUI[] componentsInChildren = ((Component)dropdown).GetComponentsInChildren(true); foreach (TextMeshProUGUI val in componentsInChildren) { ((TMP_Text)val).fontSize = 14f; } ShrinkDropdownEntries(dropdown, 15f); ExpandDropdownEntryWidths(dropdown); int num = ResolveDropdownRestoreIndex(automationId, list); dropdown.SetIndex(num); string optionName = ((num >= 0 && num < list.Count) ? list[num] : ""); UpdateAutomationDropdownSelection(automationId, num, optionName); AttachHoverPreviewHandlers(dropdown, automationId, list); } private void AttachHoverPreviewHandlers(GameUISelectableDropdown dropdown, string automationId, List options) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown if (hoverPreview == null) { return; } GameObject dropdownList = GetDropdownList(dropdown); if ((Object)(object)dropdownList == (Object)null) { return; } SeedExplorerHoverPreview.PreviewKind kind = GetPreviewKindForAutomation(automationId); int num = 0; foreach (Transform item in dropdownList.transform) { Transform val = item; if (((Object)val).name.StartsWith("Dropdown entry", StringComparison.Ordinal)) { int num2 = num; int num3 = num2; if (num3 >= options.Count) { break; } string optionName = options[num3]; EventTrigger val2 = ((Component)val).gameObject.GetComponent() ?? ((Component)val).gameObject.AddComponent(); Entry val3 = new Entry { eventID = (EventTriggerType)0 }; ((UnityEvent)(object)val3.callback).AddListener((UnityAction)delegate { hoverPreview.Show(kind, optionName); }); val2.triggers.Add(val3); Entry val4 = new Entry { eventID = (EventTriggerType)1 }; ((UnityEvent)(object)val4.callback).AddListener((UnityAction)delegate { hoverPreview.Hide(); }); val2.triggers.Add(val4); num++; } } } private static SeedExplorerHoverPreview.PreviewKind GetPreviewKindForAutomation(string automationId) { return NormalizeAutomationDropdownId(automationId) switch { "primarycard" => SeedExplorerHoverPreview.PreviewKind.PrimaryCard, "secondarycard" => SeedExplorerHoverPreview.PreviewKind.SecondaryCard, "unitcard" => SeedExplorerHoverPreview.PreviewKind.UnitCard, "artifact" => SeedExplorerHoverPreview.PreviewKind.Artifact, "upgrade" => SeedExplorerHoverPreview.PreviewKind.ChampionUpgrade, _ => SeedExplorerHoverPreview.PreviewKind.None, }; } internal SeedExplorerHoverPreview.State HoverDropdownOptionForAutomation(string automationId, int optionIndex) { EnsureSeedExplorerForAutomation(); if (hoverPreview == null) { throw new InvalidOperationException("Hover preview panel was not initialized."); } string text = NormalizeAutomationDropdownId(automationId); List dropdownOptionsForAutomation = GetDropdownOptionsForAutomation(text); if (optionIndex < 0 || optionIndex >= dropdownOptionsForAutomation.Count) { throw new ArgumentOutOfRangeException("optionIndex", $"Hover option index {optionIndex} was outside the option range for {text}."); } hoverPreview.Show(GetPreviewKindForAutomation(text), dropdownOptionsForAutomation[optionIndex]); return hoverPreview.CurrentState; } internal SeedExplorerHoverPreview.State GetHoverPreviewStateForAutomation() { return (hoverPreview != null) ? hoverPreview.CurrentState : new SeedExplorerHoverPreview.State(); } internal SeedExplorerHoverPreview.State HoverResultCellForAutomation(int rowIndex, string columnId) { EnsureSeedExplorerForAutomation(); if (hoverPreview == null) { throw new InvalidOperationException("Hover preview panel was not initialized."); } string text = SeedExplorerUiAutomationIds.NormalizeResultColumnId(columnId); if (!SeedExplorerUiAutomationIds.IsResultColumnId(text)) { throw new ArgumentException("Unknown result column id: '" + columnId + "'. Expected one of: " + string.Join(", ", SeedExplorerUiAutomationIds.ResultColumnIds), "columnId"); } if (!resultCellHoverRegistry.TryGetValue((rowIndex, text), out (string, SeedExplorerHoverPreview.PreviewKind) value)) { throw new ArgumentOutOfRangeException("rowIndex", "No registered result cell for row " + rowIndex + " column '" + text + "'. Available rows: 0.." + Math.Max(0, (resultCellHoverRegistry.Count == 0) ? (-1) : resultCellHoverRegistry.Keys.Max(((int row, string columnId) k) => k.row))); } hoverPreview.Show(value.Item2, value.Item1); return hoverPreview.CurrentState; } internal ResultCellClickAutomationState DispatchClickOnResultCellForAutomation(int rowIndex, string columnId) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) EnsureSeedExplorerForAutomation(); string text = SeedExplorerUiAutomationIds.NormalizeResultColumnId(columnId); if (!SeedExplorerUiAutomationIds.IsResultColumnId(text)) { throw new ArgumentException("Unknown result column id: '" + columnId + "'. Expected one of: " + string.Join(", ", SeedExplorerUiAutomationIds.ResultColumnIds), "columnId"); } if (!resultCellLabelObjects.TryGetValue((rowIndex, text), out var value) || (Object)(object)value == (Object)null) { throw new ArgumentOutOfRangeException("rowIndex", "No registered result cell GameObject for row " + rowIndex + " column '" + text + "'. Available rows: 0.." + Math.Max(0, (resultCellLabelObjects.Count == 0) ? (-1) : resultCellLabelObjects.Keys.Max(((int row, string columnId) k) => k.row))); } string name = ((Object)value).name; EventSystem current = EventSystem.current; PointerEventData val = new PointerEventData(current) { button = (InputButton)0, clickCount = 1, clickTime = Time.unscaledTime, position = RectTransformUtility.WorldToScreenPoint((Camera)null, value.transform.position) }; val.pointerPress = value; val.rawPointerPress = value; RaycastResult pointerCurrentRaycast = default(RaycastResult); ((RaycastResult)(ref pointerCurrentRaycast)).gameObject = value; val.pointerCurrentRaycast = pointerCurrentRaycast; val.pointerPressRaycast = val.pointerCurrentRaycast; GameObject eventHandler = ExecuteEvents.GetEventHandler(value); string handlerObjectName = ""; if ((Object)(object)eventHandler != (Object)null) { try { handlerObjectName = ((Object)eventHandler).name; } catch (MissingReferenceException) { handlerObjectName = ""; } try { ExecuteEvents.Execute(eventHandler, (BaseEventData)(object)val, ExecuteEvents.pointerClickHandler); } catch (Exception ex) { Plugin.LogError("DispatchClickOnResultCellForAutomation: Execute threw " + ex.GetType().Name + ": " + ex.Message + "\n" + ex.StackTrace); throw; } } int? chosenSeed = null; if (seedExplorer != null && seedExplorer.SelectedSeedResult != null) { chosenSeed = seedExplorer.SelectedSeedResult.Seed; } return new ResultCellClickAutomationState { RowIndex = rowIndex, Column = text, TargetObjectName = name, HandlerObjectName = handlerObjectName, DialogOpen = IsOpenForAutomation(), ChosenSeed = chosenSeed }; } private int ResolveDropdownRestoreIndex(string automationId, List options) { if (seedExplorer == null || seedExplorer.Filter == null || options == null || options.Count == 0) { return 0; } string persisted; switch (NormalizeAutomationDropdownId(automationId)) { case "primarycard": persisted = seedExplorer.Filter.PrimaryCard; break; case "secondarycard": persisted = seedExplorer.Filter.SecondaryCard; break; case "unitcard": persisted = seedExplorer.Filter.UnitCard; break; case "artifact": persisted = seedExplorer.Filter.Artifact; break; case "upgrade": persisted = seedExplorer.Filter.Upgrade; break; default: persisted = null; break; } if (string.IsNullOrEmpty(persisted)) { return 0; } int num = options.FindIndex((string option) => string.Equals(option, persisted, StringComparison.Ordinal)); return (num >= 0) ? num : 0; } private GameUISelectableDropdown CreateDropdown(Transform target, List options, string automationId) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown GameUISelectableDropdown val = Object.FindObjectOfType(true); GameUISelectableDropdown dropdown = Object.Instantiate(val); ((Object)target).name = SeedExplorerUiAutomationIds.DropdownCellObjectName(automationId); ((Object)dropdown).name = SeedExplorerUiAutomationIds.DropdownObjectName(automationId); ((Component)dropdown).transform.SetParent(target, false); RectTransform component = ((Component)dropdown).GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; Object.DestroyImmediate((Object)(object)((Component)dropdown).GetComponent()); Object.DestroyImmediate((Object)(object)((Component)dropdown).GetComponent()); Transform obj = ((Component)dropdown).transform.Find("Bg"); RectTransform val2 = ((obj != null) ? ((Component)obj).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; Image component2 = ((Component)val2).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.type = (Type)1; component2.preserveAspect = false; } } LayoutElement val3 = ((Component)dropdown).gameObject.AddComponent(); val3.minWidth = 0f; val3.flexibleWidth = 1f; val3.minHeight = 70f; val3.preferredHeight = 70f; Transform obj2 = ((Component)dropdown).transform.Find("Value"); RectTransform val4 = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.anchorMin = new Vector2(0f, 0f); val4.anchorMax = new Vector2(1f, 1f); val4.offsetMin = new Vector2(8f, val4.offsetMin.y); val4.offsetMax = new Vector2(-24f, val4.offsetMax.y); } Transform obj3 = ((Component)dropdown).transform.Find("Bg"); Image val5 = ((obj3 != null) ? ((Component)obj3).GetComponent() : null); if ((Object)(object)val5 != (Object)null) { val5.preserveAspect = false; val5.type = (Type)1; } ((UnityEvent)((Button)dropdown).onClick).AddListener((UnityAction)delegate { CoreInputControlMapping val6 = default(CoreInputControlMapping); ((CoreInput)InputManager.Inst).TryGetSignaledInputMapping(MappingID.op_Implicit((Enum)(object)(Controls)19), ref val6); dropdown.ApplyScreenInput(val6, (IGameUIComponent)(object)dropdown, (Controls)19); }); return dropdown; } private void RegisterAutomationDropdown(string id, GameUISelectableDropdown dropdown) { automationDropdowns[NormalizeAutomationDropdownId(id)] = dropdown; } private void DumpDropdownAncestors(GameUISelectableDropdown dd) { //IL_0065: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)("── Ancestor chain for " + ((Object)dd).name + " ──")); Transform val = ((Component)dd).transform; while ((Object)(object)val != (Object)null) { RectTransform component = ((Component)val).GetComponent(); LayoutElement component2 = ((Component)val).GetComponent(); HorizontalLayoutGroup component3 = ((Component)val).GetComponent(); VerticalLayoutGroup component4 = ((Component)val).GetComponent(); ContentSizeFitter component5 = ((Component)val).GetComponent(); string text = $"{((Object)val).name} | RT anchors[{component.anchorMin}->{component.anchorMax}] offs[{component.offsetMin}->{component.offsetMax}] sizeDelta{component.sizeDelta}"; if ((Object)(object)component2 != (Object)null) { text += $" LE(minW:{component2.minWidth},flexW:{component2.flexibleWidth})"; } if ((Object)(object)component3 != (Object)null) { text += $" HLG(childControlW:{((HorizontalOrVerticalLayoutGroup)component3).childControlWidth},forceExpandW:{((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth})"; } if ((Object)(object)component4 != (Object)null) { text += $" VLG(childControlW:{((HorizontalOrVerticalLayoutGroup)component4).childControlWidth},forceExpandW:{((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth})"; } if ((Object)(object)component5 != (Object)null) { text += $" CSF(H:{component5.horizontalFit},V:{component5.verticalFit})"; } Debug.Log((object)text); val = val.parent; } } private void SetupDropdownButtonListeners(GameUISelectableDropdown targetDropdown) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown GameUISelectableButton[] componentsInChildren = ((Component)targetDropdown).GetComponentsInChildren(true); foreach (GameUISelectableButton button in componentsInChildren) { if (!((Object)(object)button == (Object)(object)targetDropdown)) { ((UnityEvent)((Button)button).onClick).AddListener((UnityAction)delegate { CoreInputControlMapping val = default(CoreInputControlMapping); ((CoreInput)InputManager.Inst).TryGetSignaledInputMapping(MappingID.op_Implicit((Enum)(object)(Controls)19), ref val); targetDropdown.ApplyScreenInput(val, (IGameUIComponent)(object)button, (Controls)19); }); } } } } public class SeedExplorerFooterButton : GameUISelectableButton { public static TextMeshProUGUI ChosenSeedLabel { get; private set; } public static string FormatChosenSeedLabel(int? seed) { if (!seed.HasValue) { return ""; } return "Chosen Seed: " + seed.Value.ToString("X8"); } public static void RefreshChosenSeedLabel() { if (!((Object)(object)ChosenSeedLabel == (Object)null)) { int? seed = SeedExplorer.Instance?.SelectedSeedResult?.Seed; ((TMP_Text)ChosenSeedLabel).text = FormatChosenSeedLabel(seed); } } public static GameUISelectableButton Instantiate(RunSetupScreen runSetupScreen) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown UIFooter val = Object.FindObjectOfType(); Transform val2 = ((Component)val).transform.Find("Swap Champion Button"); Transform val3 = Object.Instantiate(val2, ((Component)val).transform); ((Object)val3).name = SeedExplorerUiAutomationIds.ChooseSeedButtonObjectName; ((TMP_Text)((Component)val3.Find("Label")).GetComponent()).text = "Choose Seed"; GameUISelectableButton component = ((Component)val3).GetComponent(); ((UnityEvent)((Button)component).onClick).AddListener((UnityAction)delegate { RunSetupContext runSetupContext = RunSetupContext.TryCapture(runSetupScreen); string key = ((runSetupContext != null) ? runSetupContext.Signature : "unknown-context"); SeedExplorerDialog seedExplorerDialog = ModRegistry.GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog != (Object)null) { seedExplorerDialog.Open(key); } }); EnsureChosenSeedLabel(val); RefreshChosenSeedLabel(); return component; } private static void EnsureChosenSeedLabel(UIFooter uiFooter) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ChosenSeedLabel != (Object)null) || !((Object)(object)((Component)ChosenSeedLabel).gameObject != (Object)null)) { GameObject val = new GameObject(SeedExplorerUiAutomationIds.ChosenSeedFooterLabelObjectName, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)uiFooter).transform, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(1f, 0f); component.anchorMax = new Vector2(1f, 0f); component.pivot = new Vector2(1f, 0f); component.anchoredPosition = new Vector2(-24f, 12f); component.sizeDelta = new Vector2(420f, 28f); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = ""; ((TMP_Text)val2).fontSize = 18f; ((TMP_Text)val2).alignment = (TextAlignmentOptions)4100; ((Graphic)val2).color = new Color(1f, 0.55f, 0.25f, 1f); ((Graphic)val2).raycastTarget = false; ChosenSeedLabel = val2; } } } internal sealed class SeedExplorerHoverPreview { public enum PreviewKind { None, PrimaryCard, SecondaryCard, UnitCard, Artifact, ChampionUpgrade, Enhancer } public sealed class State { public bool Visible; public PreviewKind Kind; public string Title = ""; public string Body = ""; public bool VisualReady; public string VisualKind = ""; public string VisualSource = ""; public string ResolvedTitle = ""; public string ResolvedBody = ""; public string RenderedTitle = ""; public string RenderedDescription = ""; public string UpgradeBaseCardName = ""; public bool HasArt; public bool HasDescription; public bool LeftAnchored; public bool BackgroundReady; public string BackgroundSource = ""; public int BackgroundGraphicCount; public float BackgroundLeft; public float BackgroundTop; public float BackgroundRight; public float BackgroundBottom; public float PanelLeft; public float PanelTop; public float PanelWidth; public float PanelHeight; public int VisualChildCount; public float VisualWidth; public float VisualHeight; public float ScreenWidth; public float ScreenHeight; public float ContentLeft; public float ContentTop; public float ContentRight; public float ContentBottom; public int CorruptAssetDispatchCount; public float ForegroundLeft; public float ForegroundTop; public float ForegroundRight; public float ForegroundBottom; } private const float DefaultCardWidth = 480f; private const float DefaultCardHeight = 720f; private const float ScreenMargin = 24f; private const float ContentScreenMargin = 8f; private const int PreviewSortingOrder = 32000; private const string OverlayCanvasName = "MTSeedExplorer Hover Preview Overlay Canvas"; private readonly GameObject root; private readonly RectTransform rootRT; private readonly Canvas rootCanvas; private readonly State state = new State(); private CardUI cardClone; private RelicInfoUI relicClone; private GameObject relicBackgroundClone; private string cardSource = ""; private string relicSource = ""; private string relicBackgroundSource = ""; private float currentPanelWidth = 480f; private float currentPanelHeight = 720f; private static bool _preloadStarted; private static bool _preloadCompleted; private RectTransform visualHost => rootRT; public State CurrentState => state; public GameObject Root => root; internal static bool IsPreloadCompleted => _preloadCompleted; internal static bool IsPreloadStarted => _preloadStarted; public SeedExplorerHoverPreview(Transform parent) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { throw new ArgumentNullException("parent"); } rootCanvas = GetOrCreateOverlayCanvas(); root = new GameObject(SeedExplorerUiAutomationIds.HoverPreviewPanelObjectName, new Type[2] { typeof(RectTransform), typeof(CanvasGroup) }); root.transform.SetParent(((Object)(object)rootCanvas != (Object)null) ? ((Component)rootCanvas).transform : parent, false); rootRT = root.GetComponent(); ConfigureOverlayCanvas(rootCanvas); CanvasGroup component = root.GetComponent(); component.blocksRaycasts = false; component.interactable = false; rootRT.anchorMin = new Vector2(1f, 1f); rootRT.anchorMax = new Vector2(1f, 1f); rootRT.pivot = new Vector2(1f, 1f); rootRT.anchoredPosition = new Vector2(-24f, -24f); rootRT.sizeDelta = new Vector2(480f, 720f); LayoutElement val = root.AddComponent(); val.ignoreLayout = true; root.transform.SetAsLastSibling(); AppDialogNotificationsPatches.SuppressCorruptAssetSignal = true; Hide(); } private static Canvas GetOrCreateOverlayCanvas() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00ac: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("MTSeedExplorer Hover Preview Overlay Canvas"); if ((Object)(object)val != (Object)null) { Canvas component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ConfigureOverlayCanvas(component); return component; } } GameObject val2 = new GameObject("MTSeedExplorer Hover Preview Overlay Canvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(CanvasGroup) }); Canvas component2 = val2.GetComponent(); ConfigureOverlayCanvas(component2); RectTransform component3 = val2.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.pivot = new Vector2(0.5f, 0.5f); component3.anchoredPosition = Vector2.zero; component3.sizeDelta = Vector2.zero; } CanvasGroup component4 = val2.GetComponent(); if ((Object)(object)component4 != (Object)null) { component4.blocksRaycasts = false; component4.interactable = false; } return component2; } private static void ConfigureOverlayCanvas(Canvas canvas) { if (!((Object)(object)canvas == (Object)null)) { canvas.renderMode = (RenderMode)0; canvas.overrideSorting = true; canvas.sortingOrder = 32000; CanvasScaler component = ((Component)canvas).GetComponent(); if ((Object)(object)component != (Object)null) { component.uiScaleMode = (ScaleMode)0; component.scaleFactor = 1f; } } } public void Hide() { state.Visible = false; state.Kind = PreviewKind.None; state.Title = ""; state.Body = ""; state.VisualReady = false; state.VisualKind = ""; state.VisualSource = ""; state.ResolvedTitle = ""; state.ResolvedBody = ""; state.RenderedTitle = ""; state.RenderedDescription = ""; state.UpgradeBaseCardName = ""; state.HasArt = false; state.HasDescription = false; state.LeftAnchored = false; state.BackgroundReady = false; state.BackgroundSource = ""; state.BackgroundGraphicCount = 0; state.BackgroundLeft = 0f; state.BackgroundTop = 0f; state.BackgroundRight = 0f; state.BackgroundBottom = 0f; state.PanelLeft = 0f; state.PanelTop = 0f; state.PanelWidth = 0f; state.PanelHeight = 0f; state.VisualChildCount = 0; state.VisualWidth = 0f; state.VisualHeight = 0f; state.ScreenWidth = Screen.width; state.ScreenHeight = Screen.height; state.ContentLeft = 0f; state.ContentTop = 0f; state.ContentRight = 0f; state.ContentBottom = 0f; state.ForegroundLeft = 0f; state.ForegroundTop = 0f; state.ForegroundRight = 0f; state.ForegroundBottom = 0f; state.CorruptAssetDispatchCount = 0; DeactivateClones(); if ((Object)(object)root != (Object)null) { root.SetActive(false); } } public void Show(PreviewKind kind, string optionName) { if (string.IsNullOrEmpty(optionName) || optionName == "") { Hide(); return; } state.Visible = true; state.Kind = kind; state.Title = optionName; state.Body = ""; state.VisualReady = false; state.VisualKind = ""; state.VisualSource = ""; state.ResolvedTitle = ""; state.ResolvedBody = ""; state.RenderedTitle = ""; state.RenderedDescription = ""; state.UpgradeBaseCardName = ""; state.HasArt = false; state.HasDescription = false; state.LeftAnchored = ShouldPlaceOnLeft(kind); state.BackgroundReady = false; state.BackgroundSource = ""; state.BackgroundGraphicCount = 0; state.BackgroundLeft = 0f; state.BackgroundTop = 0f; state.BackgroundRight = 0f; state.BackgroundBottom = 0f; state.PanelLeft = 0f; state.PanelTop = 0f; state.PanelWidth = 0f; state.PanelHeight = 0f; state.VisualChildCount = 0; state.VisualWidth = 0f; state.VisualHeight = 0f; state.ScreenWidth = Screen.width; state.ScreenHeight = Screen.height; state.ContentLeft = 0f; state.ContentTop = 0f; state.ContentRight = 0f; state.ContentBottom = 0f; state.ForegroundLeft = 0f; state.ForegroundTop = 0f; state.ForegroundRight = 0f; state.ForegroundBottom = 0f; state.CorruptAssetDispatchCount = 0; AppDialogNotificationsPatches.ResetDispatchCount(); EnforcePanelGeometry(); if ((Object)(object)root != (Object)null && !root.activeSelf) { root.SetActive(true); } DeactivateClones(); try { PopulateVisual(kind, optionName); } catch (Exception ex) { state.VisualReady = false; state.Body = "(visual error: " + ex.Message + ")"; Plugin.LogError("Hover preview failed for '" + optionName + "': " + ex); } EnforcePanelGeometry(); AdjustPanelToFitRenderedContent(); CaptureGeometry(); } private void DeactivateClones() { if ((Object)(object)cardClone != (Object)null) { ((Component)cardClone).gameObject.SetActive(false); } if ((Object)(object)relicClone != (Object)null) { ((Component)relicClone).gameObject.SetActive(false); } if ((Object)(object)relicBackgroundClone != (Object)null) { relicBackgroundClone.SetActive(false); } } private void EnforcePanelGeometry() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rootRT == (Object)null)) { bool flag = ShouldPlaceOnLeft(state.Kind); state.LeftAnchored = flag; rootRT.anchorMin = new Vector2(flag ? 0f : 1f, 1f); rootRT.anchorMax = new Vector2(flag ? 0f : 1f, 1f); rootRT.pivot = new Vector2(flag ? 0f : 1f, 1f); rootRT.anchoredPosition = new Vector2(flag ? 24f : (-24f), -24f); rootRT.sizeDelta = new Vector2(currentPanelWidth, currentPanelHeight); Transform parent = ((Transform)rootRT).parent; Vector3 val = (((Object)(object)parent != (Object)null) ? parent.lossyScale : Vector3.one); float num = ((val.x != 0f) ? (1f / val.x) : 1f); float num2 = ((val.y != 0f) ? (1f / val.y) : 1f); ((Transform)rootRT).localScale = new Vector3(num, num2, 1f); LayoutElement component = root.GetComponent(); if ((Object)(object)component != (Object)null) { component.ignoreLayout = true; } if ((Object)(object)rootCanvas != (Object)null) { rootCanvas.overrideSorting = true; rootCanvas.sortingOrder = 32000; } root.transform.SetAsLastSibling(); } } private void AdjustPanelToFitRenderedContent() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rootRT == (Object)null || (Object)(object)visualHost == (Object)null) { return; } Canvas.ForceUpdateCanvases(); Rect val = ComputeContentBoundsForChild((Transform)(object)visualHost); if (!(((Rect)(ref val)).width <= 0f) && !(((Rect)(ref val)).height <= 0f)) { float num = 0f; if (((Rect)(ref val)).xMin < 8f) { num = 8f - ((Rect)(ref val)).xMin; } else if (((Rect)(ref val)).xMax > (float)Screen.width - 8f) { num = (float)Screen.width - 8f - ((Rect)(ref val)).xMax; } float num2 = 0f; if (((Rect)(ref val)).yMax > (float)Screen.height - 8f) { num2 = (float)Screen.height - 8f - ((Rect)(ref val)).yMax; } else if (((Rect)(ref val)).yMin < 8f) { num2 = 8f - ((Rect)(ref val)).yMin; } if (!(Mathf.Abs(num) <= 0.5f) || !(Mathf.Abs(num2) <= 0.5f)) { RectTransform obj = rootRT; obj.anchoredPosition += ScreenDeltaToAnchoredDelta(new Vector2(num, num2)); Canvas.ForceUpdateCanvases(); } } } private Vector2 ScreenDeltaToAnchoredDelta(Vector2 screenDelta) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00e3: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(((Object)(object)rootRT != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { Canvas componentInParent = ((Component)val).GetComponentInParent(); Camera val2 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null); Vector2 val3 = default(Vector2); Vector2 val4 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.zero, val2, ref val3) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, screenDelta, val2, ref val4)) { return val4 - val3; } } Transform val5 = (((Object)(object)rootRT != (Object)null) ? ((Transform)rootRT).parent : null); Vector3 val6 = (((Object)(object)val5 != (Object)null) ? val5.lossyScale : Vector3.one); float num = ((Mathf.Abs(val6.x) > 0.0001f) ? val6.x : 1f); float num2 = ((Mathf.Abs(val6.y) > 0.0001f) ? val6.y : 1f); return new Vector2(screenDelta.x / num, screenDelta.y / num2); } private static bool ShouldPlaceOnLeft(PreviewKind kind) { return kind == PreviewKind.Artifact || kind == PreviewKind.ChampionUpgrade || kind == PreviewKind.Enhancer; } private void CaptureGeometry() { //IL_0068: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) state.ScreenWidth = Screen.width; state.ScreenHeight = Screen.height; state.CorruptAssetDispatchCount = AppDialogNotificationsPatches.DispatchCount; if ((Object)(object)root == (Object)null) { return; } Canvas.ForceUpdateCanvases(); RectTransform component = root.GetComponent(); if ((Object)(object)component != (Object)null) { Rect val = ComputeScreenRect(component); state.PanelLeft = ((Rect)(ref val)).xMin; state.PanelTop = (float)Screen.height - ((Rect)(ref val)).yMax; state.PanelWidth = ((Rect)(ref val)).width; state.PanelHeight = ((Rect)(ref val)).height; } if ((Object)(object)visualHost != (Object)null) { state.VisualChildCount = ((Transform)visualHost).childCount; Rect val2 = ComputeScreenRect(visualHost); state.VisualWidth = ((Rect)(ref val2)).width; state.VisualHeight = ((Rect)(ref val2)).height; Rect val3 = ComputeContentBoundsForChild((Transform)(object)visualHost); if (((Rect)(ref val3)).width > 0f && ((Rect)(ref val3)).height > 0f) { state.ContentLeft = ((Rect)(ref val3)).xMin; state.ContentTop = (float)Screen.height - ((Rect)(ref val3)).yMax; state.ContentRight = ((Rect)(ref val3)).xMax; state.ContentBottom = (float)Screen.height - ((Rect)(ref val3)).yMin; } } if ((Object)(object)relicBackgroundClone != (Object)null && relicBackgroundClone.activeInHierarchy) { Rect val4 = ComputeContentBoundsForChild(relicBackgroundClone.transform); if (((Rect)(ref val4)).width > 0f && ((Rect)(ref val4)).height > 0f) { state.BackgroundLeft = ((Rect)(ref val4)).xMin; state.BackgroundTop = (float)Screen.height - ((Rect)(ref val4)).yMax; state.BackgroundRight = ((Rect)(ref val4)).xMax; state.BackgroundBottom = (float)Screen.height - ((Rect)(ref val4)).yMin; } } if ((Object)(object)relicClone != (Object)null && ((Component)relicClone).gameObject.activeInHierarchy) { Rect val5 = ComputeContentBoundsForChild(((Component)relicClone).transform); if (((Rect)(ref val5)).width > 0f && ((Rect)(ref val5)).height > 0f) { state.ForegroundLeft = ((Rect)(ref val5)).xMin; state.ForegroundTop = (float)Screen.height - ((Rect)(ref val5)).yMax; state.ForegroundRight = ((Rect)(ref val5)).xMax; state.ForegroundBottom = (float)Screen.height - ((Rect)(ref val5)).yMin; } } else if ((Object)(object)cardClone != (Object)null && ((Component)cardClone).gameObject.activeInHierarchy) { Rect val6 = ComputeContentBoundsForChild(((Component)cardClone).transform); if (((Rect)(ref val6)).width > 0f && ((Rect)(ref val6)).height > 0f) { state.ForegroundLeft = ((Rect)(ref val6)).xMin; state.ForegroundTop = (float)Screen.height - ((Rect)(ref val6)).yMax; state.ForegroundRight = ((Rect)(ref val6)).xMax; state.ForegroundBottom = (float)Screen.height - ((Rect)(ref val6)).yMin; } } } private static Rect ComputeScreenRect(RectTransform rt) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0074: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); Camera val = null; Canvas componentInParent = ((Component)rt).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode > 0) { val = componentInParent.worldCamera; } Vector2 val2 = RectTransformUtility.WorldToScreenPoint(val, array[0]); Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val, array[2]); float num = Mathf.Min(val2.x, val3.x); float num2 = Mathf.Max(val2.x, val3.x); float num3 = Mathf.Min(val2.y, val3.y); float num4 = Mathf.Max(val2.y, val3.y); return new Rect(num, num3, num2 - num, num4 - num3); } private static string KindLabel(PreviewKind kind) { return kind switch { PreviewKind.PrimaryCard => "Primary card", PreviewKind.SecondaryCard => "Secondary card", PreviewKind.UnitCard => "Unit card", PreviewKind.Artifact => "Artifact", PreviewKind.ChampionUpgrade => "Champion upgrade", PreviewKind.Enhancer => "Enhancer", _ => "", }; } private void PopulateVisual(PreviewKind kind, string optionName) { SaveManager val = (((Object)(object)AllGameManagers.Instance != (Object)null) ? AllGameManagers.Instance.GetSaveManager() : null); AllGameData val2 = ((val != null) ? val.GetAllGameData() : null); if ((Object)(object)val2 == (Object)null) { state.Body = "(game data not available)"; return; } switch (kind) { case PreviewKind.PrimaryCard: case PreviewKind.SecondaryCard: case PreviewKind.UnitCard: { CardData val5 = val2.FindCardDataByName(optionName) ?? FindCardDataByEnglishName(val2, optionName); if ((Object)(object)val5 == (Object)null) { state.Body = "(card '" + optionName + "' not found)"; } else { ShowCardClone(val5, val); } break; } case PreviewKind.Artifact: { CollectableRelicData val6 = val2.FindCollectableRelicDataByName(optionName) ?? FindRelicDataByEnglishName(val2, optionName); if ((Object)(object)val6 == (Object)null) { state.Body = "(artifact '" + optionName + "' not found)"; } else { ShowRelicClone((RelicData)(object)val6, kind); } break; } case PreviewKind.ChampionUpgrade: case PreviewKind.Enhancer: { EnhancerData val3 = val2.FindEnhancerDataByName(optionName) ?? FindEnhancerDataByEnglishName(val2, optionName); if ((Object)(object)val3 != (Object)null) { ShowRelicClone((RelicData)(object)val3, kind); break; } CardUpgradeData val4 = FindCardUpgradeDataByEnglishName(val2, optionName); if ((Object)(object)val4 != (Object)null) { ShowChampionUpgradeCardClone(val4, val); } else { state.Body = "(enhancer '" + optionName + "' not found)"; } break; } } } private static CardData FindCardDataByEnglishName(AllGameData allGameData, string englishName) { foreach (CardData allCardDatum in allGameData.GetAllCardData()) { if ((Object)(object)allCardDatum != (Object)null && string.Equals(allCardDatum.Cheat_GetNameEnglish(), englishName, StringComparison.OrdinalIgnoreCase)) { return allCardDatum; } } return null; } private static CollectableRelicData FindRelicDataByEnglishName(AllGameData allGameData, string englishName) { foreach (CollectableRelicData allCollectableRelicDatum in allGameData.GetAllCollectableRelicData()) { if ((Object)(object)allCollectableRelicDatum != (Object)null && string.Equals(((RelicData)allCollectableRelicDatum).Cheat_GetNameEnglish(), englishName, StringComparison.OrdinalIgnoreCase)) { return allCollectableRelicDatum; } } return null; } private static EnhancerData FindEnhancerDataByEnglishName(AllGameData allGameData, string englishName) { foreach (EnhancerData allEnhancerDatum in allGameData.GetAllEnhancerData()) { if ((Object)(object)allEnhancerDatum != (Object)null && string.Equals(((RelicData)allEnhancerDatum).Cheat_GetNameEnglish(), englishName, StringComparison.OrdinalIgnoreCase)) { return allEnhancerDatum; } } return null; } internal static void PreloadCardArt() { try { SaveManager val = (((Object)(object)AllGameManagers.Instance != (Object)null) ? AllGameManagers.Instance.GetSaveManager() : null); AllGameData val2 = ((val != null) ? val.GetAllGameData() : null); AssetLoadingManager inst = AssetLoadingManager.GetInst(); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)inst == (Object)null)) { _preloadCompleted = false; _preloadStarted = true; inst.LoadCardsForCompendium((IEnumerable)val2.GetAllCardData(), (DoesOwnerPassFilter)null, (Action)delegate { _preloadCompleted = true; }); } } catch (Exception ex) { Plugin.LogError("PreloadCardArt failed: " + ex); _preloadCompleted = true; } } private static CardUpgradeData FindCardUpgradeDataByEnglishName(AllGameData allGameData, string englishName) { foreach (CardUpgradeData allCardUpgradeDatum in allGameData.GetAllCardUpgradeData()) { if ((Object)(object)allCardUpgradeDatum != (Object)null && string.Equals(allCardUpgradeDatum.Cheat_GetNameEnglish(), englishName, StringComparison.OrdinalIgnoreCase)) { return allCardUpgradeDatum; } } return null; } private void ShowChampionUpgradeCardClone(CardUpgradeData upgradeData, SaveManager saveManager) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown if ((Object)(object)upgradeData == (Object)null) { state.Body = "(upgrade data not available)"; return; } if ((Object)(object)saveManager == (Object)null) { state.Body = "(save manager not available for upgrade preview)"; return; } CardState val = FindActiveChampionState(saveManager); if (val == null) { state.Body = "(active champion card not available for upgrade preview)"; return; } CardData val2 = ResolveChampionCardData(saveManager, val); if ((Object)(object)val2 == (Object)null) { state.Body = "(champion card not available for upgrade preview)"; return; } state.UpgradeBaseCardName = val2.Cheat_GetNameEnglish(); try { CardState val3 = new CardState(val2, saveManager, false, false); AllGameManagers instance = AllGameManagers.Instance; RelicManager val4 = (((Object)(object)instance != (Object)null) ? instance.GetRelicManager() : null); if ((Object)(object)val4 != (Object)null) { val4.ApplyCardStateModifiers(val3, true); } CardUpgradeState val5 = new CardUpgradeState(); val5.Setup(upgradeData, false, false); val3.ApplyPermanentUpgrade(val5, saveManager, true, (string)null); ShowCardStateClone(val3, saveManager); } catch (Exception ex) { state.VisualReady = false; state.Body = "(upgrade preview failed: " + ex.Message + ")"; Plugin.LogError("Champion upgrade preview failed: " + ex); } } private static CardState FindActiveChampionState(SaveManager saveManager) { return (((Object)(object)saveManager != (Object)null) ? saveManager.GetDeckState() : null)?.Find((CardState card) => card != null && card.IsChampionCard()); } private static CardData ResolveChampionCardData(SaveManager saveManager, CardState championState) { AllGameData val = (((Object)(object)saveManager != (Object)null) ? saveManager.GetAllGameData() : null); string text = ((championState != null) ? championState.GetCardDataID() : ""); if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(text)) { CardData val2 = val.FindCardData(text); if ((Object)(object)val2 != (Object)null) { return val2; } } return ((Object)(object)saveManager != (Object)null && (Object)(object)saveManager.GetSubClass() != (Object)null) ? saveManager.GetSubClass().GetChampionCard(saveManager.GetSubChampionIndex()) : null; } private static T ReflectField(object target, string fieldName) where T : class { if (target == null) { return null; } Type type = target.GetType(); while (type != null) { FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(target) as T; } type = type.BaseType; } return null; } private static bool HasMeaningfulText(string text) { if (string.IsNullOrWhiteSpace(text)) { return false; } string a = text.Trim(); return !string.Equals(a, "(no description)", StringComparison.OrdinalIgnoreCase); } private static bool HasMeaningfulTitle(string text) { return !string.IsNullOrWhiteSpace(text); } private bool ValidateResolvedDiagnostics(string visualKind) { List list = new List(); if (!HasMeaningfulTitle(state.ResolvedTitle)) { list.Add("title"); } if (!HasMeaningfulText(state.ResolvedBody)) { list.Add("description"); } if (!state.HasArt) { list.Add((visualKind == "RelicInfoUI") ? "icon" : "art"); } if (list.Count == 0) { return true; } state.VisualReady = false; state.Body = "(" + visualKind + " missing " + string.Join(", ", list) + ")"; Plugin.LogError("Hover preview " + visualKind + " diagnostics incomplete for '" + state.Title + "': " + string.Join(", ", list)); return false; } private void PopulateCardDiagnostics(CardState cardState, SaveManager saveManager) { string text = ""; string text2 = ""; try { text = ((cardState != null) ? cardState.GetTitle() : ""); } catch { } try { if (cardState != null) { cardState.GenerateCardBodyText(ref text2, false, "", (CharacterState)null, (CardState)null); } } catch { try { text2 = ((cardState != null) ? cardState.GetCardText((CardStatistics)null, saveManager, false) : ""); } catch { } } state.ResolvedTitle = (string.IsNullOrEmpty(text) ? state.Title : text); state.ResolvedBody = text2 ?? ""; state.RenderedTitle = state.ResolvedTitle; state.RenderedDescription = state.ResolvedBody; state.Body = state.ResolvedBody; state.HasDescription = HasMeaningfulText(state.ResolvedBody); try { state.HasArt = cardState != null && ((Object)(object)cardState.GetCardArtPrefabVariant() != (Object)null || (Object)(object)cardState.GetSprite() != (Object)null); } catch { state.HasArt = false; } } private void PopulateRelicDiagnostics(RelicInfoUI relicInfoUI, RelicData relicData) { TMP_Text val = ReflectField(relicInfoUI, "titleLabel"); TMP_Text val2 = ReflectField(relicInfoUI, "descriptionLabel"); Image val3 = ReflectField(relicInfoUI, "icon"); state.ResolvedTitle = (((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.text)) ? val.text : state.Title); state.ResolvedBody = (((Object)(object)val2 != (Object)null) ? (val2.text ?? "") : ""); state.RenderedTitle = state.ResolvedTitle; state.RenderedDescription = state.ResolvedBody; state.Body = state.ResolvedBody; state.HasDescription = HasMeaningfulText(state.ResolvedBody); state.HasArt = (Object)(object)val3 != (Object)null && (Object)(object)val3.sprite != (Object)null; state.BackgroundGraphicCount = CountGraphicImages(((Object)(object)relicInfoUI != (Object)null) ? ((Component)relicInfoUI).gameObject : null, val3); if (!state.HasArt && (Object)(object)relicData != (Object)null) { try { state.HasArt = (Object)(object)relicData.GetIcon() != (Object)null; } catch { } } } private static int CountGraphicImages(GameObject root, Image exclude) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) if ((Object)(object)root == (Object)null) { return 0; } int num = 0; Image[] componentsInChildren = root.GetComponentsInChildren(false); foreach (Image val in componentsInChildren) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)exclude || !((Behaviour)val).enabled || (Object)(object)val.sprite == (Object)null) { continue; } RectTransform rectTransform = ((Graphic)val).rectTransform; if ((Object)(object)rectTransform != (Object)null) { Rect rect = rectTransform.rect; if (((Rect)(ref rect)).width < 16f) { continue; } rect = rectTransform.rect; if (((Rect)(ref rect)).height < 16f) { continue; } } num++; } return num; } private void ShowCardClone(CardData cardData, SaveManager saveManager) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown CardState cardState = new CardState(cardData, saveManager, true, false); ShowCardStateClone(cardState, saveManager); } private unsafe void ShowCardStateClone(CardState cardState, SaveManager saveManager) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01ae->IL01ae: Incompatible stack types: Ref vs I4 //IL_01a7->IL01ae: Incompatible stack types: I4 vs Ref //IL_01a7->IL01ae: Incompatible stack types: Ref vs I4 if ((Object)(object)cardClone == (Object)null) { if (!SeedExplorerCardPreviewPrefabs.TryGetCardPrefab(out var prefab, out var source)) { string text = string.Join(" | ", SeedExplorerCardPreviewPrefabs.AttemptLog); state.Body = "(no CardUI prefab discovered: " + text + ")"; return; } cardSource = source; cardClone = Object.Instantiate(prefab, (Transform)(object)visualHost); ((Object)cardClone).name = "MTSeedExplorer Card Clone"; ConfigureCloneRect(((Component)cardClone).gameObject); if ((Object)(object)relicClone != (Object)null) { ((Component)relicClone).gameObject.SetActive(false); } if ((Object)(object)relicBackgroundClone != (Object)null) { relicBackgroundClone.SetActive(false); } } else { if ((Object)(object)relicClone != (Object)null) { ((Component)relicClone).gameObject.SetActive(false); } if ((Object)(object)relicBackgroundClone != (Object)null) { relicBackgroundClone.SetActive(false); } } ((Component)cardClone).gameObject.SetActive(true); ConfigureCloneRect(((Component)cardClone).gameObject); try { cardClone.SetInPool(false); } catch { } PopulateCardDiagnostics(cardState, saveManager); AllGameManagers instance = AllGameManagers.Instance; RelicManager relicManager = (((Object)(object)instance != (Object)null) ? instance.GetRelicManager() : null); StateParams val = default(StateParams); val.uiState = (CardUIState)3; val.cardState = cardState; ref StateParams reference = ref val; int num; if ((Object)(object)saveManager != (Object)null) { reference = ref *(StateParams*)saveManager.GetMastery(cardState); num = (int)(ref reference); } else { num = 0; reference = ref *(StateParams*)num; num = (int)(ref reference); } Unsafe.Write(&((StateParams)num).masteryType, (MasteryType)(ref reference)); val.saveManager = saveManager; val.relicManager = relicManager; StateParams val2 = val; try { cardClone.SetCardVisibleAndInteractable(true, (HandUI)null); cardClone.ApplyStateToUI(val2); state.HasArt = state.HasArt || (Object)(object)cardClone.GetCardArtVariantInstance() != (Object)null; } catch (Exception ex) { state.VisualReady = false; state.Body = "(CardUI.ApplyStateToUI failed: " + ex.Message + ")"; Plugin.LogError("CardUI.ApplyStateToUI failed: " + ex); return; } TameClonedCardBehaviour(cardClone); DisableRaycastTargets(((Component)cardClone).gameObject); if (ValidateResolvedDiagnostics("CardUI")) { state.VisualReady = true; state.VisualKind = "CardUI"; state.VisualSource = cardSource; } } private static void DisableRaycastTargets(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Graphic[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Graphic val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.raycastTarget = false; } } CanvasGroup[] componentsInChildren2 = root.GetComponentsInChildren(true); foreach (CanvasGroup val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { val2.blocksRaycasts = false; val2.interactable = false; } } } private void ShowRelicClone(RelicData relicData, PreviewKind kind) { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) bool flag = relicData is CollectableRelicData && !(relicData is EnhancerData); int num = 0; SeedExplorerCardPreviewPrefabs.RelicPreviewRole role = ((relicData is EnhancerData) ? SeedExplorerCardPreviewPrefabs.RelicPreviewRole.Enhancer : SeedExplorerCardPreviewPrefabs.RelicPreviewRole.Artifact); if (!flag && (Object)(object)relicBackgroundClone != (Object)null) { relicBackgroundClone.SetActive(false); } if ((Object)(object)relicClone == (Object)null) { if (!SeedExplorerCardPreviewPrefabs.TryGetRelicPrefab(role, out var prefab, out var source)) { string text = string.Join(" | ", SeedExplorerCardPreviewPrefabs.AttemptLog); state.Body = "(no RelicInfoUI prefab discovered: " + text + ")"; return; } if (flag) { EnsureRelicBackgroundClone(prefab, (CollectableRelicData)(object)((relicData is CollectableRelicData) ? relicData : null)); if ((Object)(object)relicBackgroundClone == (Object)null) { return; } } relicSource = source; relicClone = Object.Instantiate(prefab, (Transform)(object)visualHost); ((Object)relicClone).name = "MTSeedExplorer Relic Clone"; StripRelicNonContentChildren(((Component)relicClone).gameObject); ConfigureCloneRect(((Component)relicClone).gameObject, updatePanelSize: false); if ((Object)(object)cardClone != (Object)null) { ((Component)cardClone).gameObject.SetActive(false); } } else if ((Object)(object)cardClone != (Object)null) { ((Component)cardClone).gameObject.SetActive(false); } if (flag && (Object)(object)relicBackgroundClone == (Object)null) { if (SeedExplorerCardPreviewPrefabs.TryGetRelicPrefab(role, out var prefab2, out var _)) { EnsureRelicBackgroundClone(prefab2, (CollectableRelicData)(object)((relicData is CollectableRelicData) ? relicData : null)); } if ((Object)(object)relicBackgroundClone == (Object)null) { return; } } ((Component)relicClone).gameObject.SetActive(true); Vector2 val = ConfigureCloneRect(((Component)relicClone).gameObject, updatePanelSize: false); if (flag) { relicBackgroundClone.SetActive(true); relicBackgroundClone.transform.SetAsFirstSibling(); Vector2 val2 = ConfigureCloneRect(relicBackgroundClone, updatePanelSize: false); currentPanelWidth = Mathf.Max(val.x, val2.x); currentPanelHeight = Mathf.Max(val.y, val2.y); state.BackgroundReady = true; state.BackgroundSource = relicBackgroundSource; num = CountGraphicImages(relicBackgroundClone, null); state.BackgroundGraphicCount = num; } else { currentPanelWidth = val.x; currentPanelHeight = val.y; } try { relicClone.Set(relicData); PopulateRelicDiagnostics(relicClone, relicData); if (flag) { FitArtifactBackgroundToRelicContent(); state.BackgroundGraphicCount += num; } } catch (Exception ex) { state.VisualReady = false; state.Body = "(RelicInfoUI.Set failed: " + ex.Message + ")"; Plugin.LogError("RelicInfoUI.Set failed: " + ex); return; } DisableRaycastTargets(((Component)relicClone).gameObject); if (ValidateResolvedDiagnostics("RelicInfoUI")) { state.VisualReady = true; state.VisualKind = "RelicInfoUI"; state.VisualSource = relicSource; } } private void EnsureRelicBackgroundClone(RelicInfoUI relicPrefab, CollectableRelicData relicData) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089->IL0089: Incompatible stack types: O vs I4 //IL_0083->IL0089: Incompatible stack types: I4 vs O //IL_0083->IL0089: Incompatible stack types: O vs I4 if ((Object)(object)relicBackgroundClone != (Object)null) { return; } if (SeedExplorerCardPreviewPrefabs.TryGetCardDraftBgItemPrefab(out var prefab, out var source)) { relicBackgroundSource = source; relicBackgroundClone = Object.Instantiate(((Component)prefab).gameObject, (Transform)(object)visualHost); ((Object)relicBackgroundClone).name = "MTSeedExplorer Relic Card Background Clone"; CardDraftBgItem component = relicBackgroundClone.GetComponent(); try { if ((Object)(object)component != (Object)null) { object obj = component; int num; if ((Object)(object)relicData != (Object)null) { obj = relicData.GetRarity(); num = (int)obj; } else { num = 0; obj = num; num = (int)obj; } ((CardDraftBgItem)num).SetRarity((CollectableRarity)obj); } } catch (Exception ex) { Plugin.LogError("CardDraftBgItem.SetRarity failed: " + ex); } ConfigureBackgroundChildren(relicBackgroundClone); DisableRaycastTargets(relicBackgroundClone); relicBackgroundClone.SetActive(false); } else { string text = string.Join(" | ", SeedExplorerCardPreviewPrefabs.AttemptLog); state.Body = "(no artifact background prefab discovered: " + text + ")"; } } private static void ConfigureBackgroundChildren(GameObject backgroundClone) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if ((Object)(object)backgroundClone == (Object)null) { return; } foreach (Transform item in backgroundClone.transform) { Transform val = item; if (((Object)val).name == "BonusCardItemHighlight") { ((Component)val).gameObject.SetActive(false); } } } private static void StripRelicNonContentChildren(GameObject relicRoot) { if ((Object)(object)relicRoot == (Object)null) { return; } Transform[] componentsInChildren = relicRoot.GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { string name = ((Object)val).name; if (name == "Selection indicator" || name == "Invis Hitbox") { ((Component)val).gameObject.SetActive(false); } } } private void FitArtifactBackgroundToRelicContent() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visualHost == (Object)null || (Object)(object)relicClone == (Object)null || (Object)(object)relicBackgroundClone == (Object)null) { return; } RectTransform component = relicBackgroundClone.GetComponent(); RectTransform component2 = ((Component)relicClone).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null)) { ((Transform)component).localScale = Vector3.one; ((Transform)component2).localScale = Vector3.one; Canvas.ForceUpdateCanvases(); if (TryGetLocalGraphicBounds(visualHost, ((Component)relicClone).gameObject, out var bounds) && TryGetLocalGraphicBounds(visualHost, relicBackgroundClone, out var bounds2) && !(((Bounds)(ref bounds)).size.x <= 1f) && !(((Bounds)(ref bounds)).size.y <= 1f) && !(((Bounds)(ref bounds2)).size.x <= 1f) && !(((Bounds)(ref bounds2)).size.y <= 1f)) { Vector3 val = ((Bounds)(ref bounds)).center - ((Bounds)(ref bounds2)).center; component.anchoredPosition += new Vector2(val.x, val.y); float num = Mathf.Max(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds2)).size.x); float num2 = Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds2)).size.y); currentPanelWidth = Mathf.Max(currentPanelWidth, num); currentPanelHeight = Mathf.Max(currentPanelHeight, num2); } } } private static bool TryGetLocalGraphicBounds(RectTransform relativeTo, GameObject root, out Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(Vector3.zero, Vector3.zero); if ((Object)(object)relativeTo == (Object)null || (Object)(object)root == (Object)null) { return false; } bool flag = false; Vector3[] array = (Vector3[])(object)new Vector3[4]; Graphic[] componentsInChildren = root.GetComponentsInChildren(false); foreach (Graphic val in componentsInChildren) { if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled || !((Component)val).gameObject.activeInHierarchy) { continue; } RectTransform rectTransform = val.rectTransform; if ((Object)(object)rectTransform == (Object)null) { continue; } Rect rect = rectTransform.rect; if (((Rect)(ref rect)).width <= 0f) { continue; } rect = rectTransform.rect; if (((Rect)(ref rect)).height <= 0f) { continue; } rectTransform.GetWorldCorners(array); for (int j = 0; j < array.Length; j++) { Vector3 val2 = ((Transform)relativeTo).InverseTransformPoint(array[j]); if (!flag) { bounds = new Bounds(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2); } } } return flag; } private Vector2 ConfigureCloneRect(GameObject clone, bool updatePanelSize = true) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) RectTransform component = clone.GetComponent(); if ((Object)(object)component == (Object)null) { return new Vector2(480f, 720f); } Vector2 nativeSize = GetNativeSize(component); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = nativeSize; ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; if (updatePanelSize) { currentPanelWidth = nativeSize.x; currentPanelHeight = nativeSize.y; } Canvas[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (Canvas val in componentsInChildren) { val.overrideSorting = false; } return nativeSize; } private static Vector2 GetNativeSize(RectTransform rt) { //IL_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rt == (Object)null) { return new Vector2(480f, 720f); } Vector2 sizeDelta = rt.sizeDelta; if (sizeDelta.x <= 1f) { sizeDelta.x = 480f; } if (sizeDelta.y <= 1f) { sizeDelta.y = 720f; } return sizeDelta; } private static void TameClonedCardBehaviour(CardUI clone) { if ((Object)(object)clone == (Object)null) { return; } try { ((Behaviour)clone).enabled = false; } catch { } } private static Rect ComputeContentBoundsForChild(Transform root) { //IL_0020: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return new Rect(0f, 0f, 0f, 0f); } Rect result = default(Rect); ((Rect)(ref result))..ctor(0f, 0f, 0f, 0f); bool flag = false; Graphic[] componentsInChildren = ((Component)root).GetComponentsInChildren(false); foreach (Graphic val in componentsInChildren) { if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled || !((Component)val).gameObject.activeInHierarchy) { continue; } Rect val2 = ComputeScreenRect(val.rectTransform); if (!(((Rect)(ref val2)).width <= 0f) && !(((Rect)(ref val2)).height <= 0f)) { if (!flag) { result = val2; flag = true; continue; } float num = Mathf.Min(((Rect)(ref result)).xMin, ((Rect)(ref val2)).xMin); float num2 = Mathf.Min(((Rect)(ref result)).yMin, ((Rect)(ref val2)).yMin); float num3 = Mathf.Max(((Rect)(ref result)).xMax, ((Rect)(ref val2)).xMax); float num4 = Mathf.Max(((Rect)(ref result)).yMax, ((Rect)(ref val2)).yMax); ((Rect)(ref result))..ctor(num, num2, num3 - num, num4 - num2); } } return result; } } internal static class SeedExplorerUiAutomationIds { internal const string ChooseSeedButton = "choose-seed"; internal const string PrimaryCardDropdown = "primarycard"; internal const string SecondaryCardDropdown = "secondarycard"; internal const string UnitCardDropdown = "unitcard"; internal const string ArtifactDropdown = "artifact"; internal const string UpgradeDropdown = "upgrade"; internal static readonly string[] DropdownIds = new string[5] { "primarycard", "secondarycard", "unitcard", "artifact", "upgrade" }; internal const string ResultColumnPrimary = "primary"; internal const string ResultColumnSecondary = "secondary"; internal const string ResultColumnUnit = "unit"; internal const string ResultColumnArtifact1 = "artifact1"; internal const string ResultColumnArtifact2 = "artifact2"; internal const string ResultColumnUpgrade1 = "upgrade1"; internal const string ResultColumnUpgrade2 = "upgrade2"; internal static readonly string[] ResultColumnIds = new string[7] { "primary", "secondary", "unit", "artifact1", "artifact2", "upgrade1", "upgrade2" }; internal static string ChooseSeedButtonObjectName => "MTSeedExplorer Choose Seed Button"; internal static string ChosenSeedFooterLabelObjectName => "MTSeedExplorer Chosen Seed Footer Label"; internal static string DialogChosenSeedLabelObjectName => "MTSeedExplorer Dialog Chosen Seed Label"; internal static string HoverPreviewPanelObjectName => "MTSeedExplorer Hover Preview Panel"; internal static string ResultsViewportObjectName => "MTSeedExplorer Results Viewport"; internal static bool IsResultColumnId(string id) { string value = NormalizeResultColumnId(id); string[] resultColumnIds = ResultColumnIds; foreach (string text in resultColumnIds) { if (text.Equals(value, StringComparison.Ordinal)) { return true; } } return false; } internal static string NormalizeResultColumnId(string id) { return (id ?? "").Trim().ToLowerInvariant(); } internal static string ResultCellLabelObjectName(int rowIndex, string columnId) { return "MTSeedExplorer Result Cell Label " + rowIndex.ToString(CultureInfo.InvariantCulture) + " " + NormalizeResultColumnId(columnId); } internal static string ResultRowObjectName(int index) { return "MTSeedExplorer Result Row " + index.ToString(CultureInfo.InvariantCulture); } internal static string DropdownCellObjectName(string id) { return "MTSeedExplorer Dropdown Cell " + id; } internal static string DropdownObjectName(string id) { return "MTSeedExplorer Dropdown " + id; } internal static string DropdownListObjectName(string id) { return "MTSeedExplorer Dropdown List " + id; } internal static bool IsDropdownId(string id) { string[] dropdownIds = DropdownIds; foreach (string text in dropdownIds) { if (text.Equals(id, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } } namespace MTSeedExplorer.HarmonyPatches { [HarmonyPatch(typeof(AppDialogNotifications))] public static class AppDialogNotificationsPatches { private static int _dispatchCount; private static int _dismissCount; internal static int DispatchCount => Interlocked.CompareExchange(ref _dispatchCount, 0, 0); internal static int DismissCount => Interlocked.CompareExchange(ref _dismissCount, 0, 0); internal static bool SuppressCorruptAssetSignal { get; set; } internal static void IncrementDismissCount() { Interlocked.Increment(ref _dismissCount); } internal static void ResetDispatchCount() { Interlocked.Exchange(ref _dispatchCount, 0); Interlocked.Exchange(ref _dismissCount, 0); } [HarmonyPrefix] [HarmonyPatch("HandleCorruptAssetSignal")] public static bool HandleCorruptAssetSignal_Prefix() { Interlocked.Increment(ref _dispatchCount); Plugin.Log($"AppDialogNotifications.HandleCorruptAssetSignal intercepted (suppress={SuppressCorruptAssetSignal})"); return !SuppressCorruptAssetSignal; } } [HarmonyPatch(typeof(Dialog))] public static class DialogShowPatches { private static readonly string[] CorruptionTextMarkers = new string[4] { "Game data files are corrupted", "may not display their art assets", "verify the integrity of the game files", "Message_CorruptedAssets" }; [HarmonyPostfix] [HarmonyPatch("Show")] public static void Show_Postfix(Dialog __instance, Data data) { if ((Object)(object)__instance == (Object)null || data == null || string.IsNullOrEmpty(data.content) || !AppDialogNotificationsPatches.SuppressCorruptAssetSignal || !IsCorruptionDialog(data.content)) { return; } try { Plugin.Log("DialogShowPatches: dismissing corrupt-asset popup that escaped main suppression."); AppDialogNotificationsPatches.IncrementDismissCount(); __instance.Close(false); } catch (Exception ex) { Plugin.LogError("DialogShowPatches dismiss failed: " + ex); } } internal static bool IsCorruptionDialog(string content) { if (string.IsNullOrEmpty(content)) { return false; } string[] corruptionTextMarkers = CorruptionTextMarkers; foreach (string value in corruptionTextMarkers) { if (content.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } internal static int DismissActiveCorruptionDialogs() { int num = 0; Dialog[] array = Resources.FindObjectsOfTypeAll(); foreach (Dialog val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } string content = ReadDialogContent(val); if (IsCorruptionDialog(content)) { try { val.Close(false); AppDialogNotificationsPatches.IncrementDismissCount(); num++; Plugin.Log("DismissActiveCorruptionDialogs closed an active corrupt-asset popup."); } catch (Exception ex) { Plugin.LogError("Failed to close active corrupt-asset popup: " + ex); } } } return num; } private static string ReadDialogContent(Dialog dialog) { try { FieldInfo field = typeof(Dialog).GetField("data", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object? value = field.GetValue(dialog); Data val = (Data)((value is Data) ? value : null); if (val != null) { return val.content ?? ""; } } FieldInfo field2 = typeof(Dialog).GetField("contentLabel", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null) { object? value2 = field2.GetValue(dialog); TMP_Text val2 = (TMP_Text)((value2 is TMP_Text) ? value2 : null); if (val2 != null) { return val2.text ?? ""; } } } catch { } return ""; } } [HarmonyPatch(typeof(AppManager))] public static class AppManagerPatches { [HarmonyPostfix] [HarmonyPatch("DoesThisBuildReportErrors")] public static void DoesThisBuildReportErrors_Postfix(ref bool __result) { __result = false; } [HarmonyPostfix] [HarmonyPatch("Update")] public static void Update_Postfix() { AutomationBridge.DrainActiveMainThreadQueue(); } } [HarmonyPatch(typeof(CardPoolHelper))] public static class CardPullHelperPatches { [HarmonyPostfix] [HarmonyPatch("GetCardsForClass", new Type[] { typeof(CardPool), typeof(ClassData), typeof(int), typeof(CollectableRarity), typeof(CollectableRarity?), typeof(SaveManager), typeof(RarityCondition), typeof(bool) })] public static void GetCardsForClass_Postfix(CardPool cardPool, ref List __result) { if (SeedExplorer.Instance.ShouldCaptureStartingCardPool && (((Object)cardPool).name == "MegaPool" || ((Object)cardPool).name == "UnitsAllBanner")) { SeedExplorer.Instance.OnStartingCardPoolGenerated(__result); } } } [HarmonyPatch(typeof(LoadScreen))] public static class LoadScreenPatches { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ScreenActiveCallback <>9__0_0; internal void b__0_0(IScreen screen) { RunSetupScreen val = (RunSetupScreen)(object)((screen is RunSetupScreen) ? screen : null); Plugin.Log("RunSetup screen-active callback firing; instantiating Choose Seed UI."); GameUISelectableButton button = SeedExplorerFooterButton.Instantiate(val); ModRegistry.RegisterSeedExplorerFooterButton(val, button); SeedExplorerDialog dialog = SeedExplorerDialog.Instantiate(val); ModRegistry.RegisterSeedExplorerDialog(val, dialog); SeedExplorerCardPreviewPrefabs.PreloadArtifactBackgroundTemplates(); Plugin.NotifyRunSetupScreenActive(val); } } [HarmonyPostfix] [HarmonyPatch("StartLoadingScreen")] public static void AddSeedExplorerButton(LoadScreen __instance, ref ScreenActiveCallback ___screenActiveCallback) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0027: 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_0032: Expected O, but got Unknown if ((int)__instance.name != 42) { return; } ScreenActiveCallback a = ___screenActiveCallback; object obj = <>c.<>9__0_0; if (obj == null) { ScreenActiveCallback val = delegate(IScreen screen) { RunSetupScreen val2 = (RunSetupScreen)(object)((screen is RunSetupScreen) ? screen : null); Plugin.Log("RunSetup screen-active callback firing; instantiating Choose Seed UI."); GameUISelectableButton button = SeedExplorerFooterButton.Instantiate(val2); ModRegistry.RegisterSeedExplorerFooterButton(val2, button); SeedExplorerDialog dialog = SeedExplorerDialog.Instantiate(val2); ModRegistry.RegisterSeedExplorerDialog(val2, dialog); SeedExplorerCardPreviewPrefabs.PreloadArtifactBackgroundTemplates(); Plugin.NotifyRunSetupScreenActive(val2); }; <>c.<>9__0_0 = val; obj = (object)val; } ___screenActiveCallback = (ScreenActiveCallback)Delegate.Combine((Delegate?)(object)a, (Delegate?)obj); } } [HarmonyPatch(typeof(PregeneratedRewardID))] public static class PregeneratedRewardIDPatches { [HarmonyPrefix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void PregeneratedRewardID_Ctor_Prefix(IRewardGiver giver, int distance, int branch, int index) { if (SeedExplorer.Instance.ShouldCaptureStartingArtifactsPregenId) { SeedExplorer.Instance.OnStartingArtifactsGenerated(giver, distance, branch, index); } } } [HarmonyPatch(typeof(CharacterState))] public static class RelicChoicePreloadPatches { [HarmonyPrefix] [HarmonyPatch("Update")] public static bool CharacterState_Update_Prefix(CharacterState __instance) { if (SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadInProgress) { return false; } if (IsRelicChoicePreloadCharacter(__instance)) { return false; } return true; } [HarmonyFinalizer] [HarmonyPatch("Update")] public static Exception CharacterState_Update_Finalizer(CharacterState __instance, Exception __exception) { if (__exception is ArgumentOutOfRangeException && IsRelicChoicePreloadCharacter(__instance)) { return null; } return __exception; } [HarmonyFinalizer] [HarmonyPatch(typeof(CharacterUI), "UpdateGradientEffect")] public static Exception CharacterUI_UpdateGradientEffect_Finalizer(Exception __exception) { if (__exception is ArgumentOutOfRangeException && Plugin.IsRunSetupScreenActive && SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadStarted) { return null; } return __exception; } [HarmonyFinalizer] [HarmonyPatch(typeof(CharacterUI), "UpdateDissolveEffect")] public static Exception CharacterUI_UpdateDissolveEffect_Finalizer(Exception __exception) { if (__exception is ArgumentOutOfRangeException && Plugin.IsRunSetupScreenActive && SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadStarted) { return null; } return __exception; } private static bool IsRelicChoicePreloadCharacter(CharacterState characterState) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)characterState == (Object)null || !Plugin.IsRunSetupScreenActive || !SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadStarted) { return false; } try { object obj; if (!((Object)(object)((Component)characterState).gameObject != (Object)null)) { obj = ""; } else { Scene scene = ((Component)characterState).gameObject.scene; obj = ((Scene)(ref scene)).name; } string a = (string)obj; int result; if (!string.Equals(a, "relic_draft", StringComparison.OrdinalIgnoreCase)) { ScreenName val = (ScreenName)4; result = (string.Equals(a, ((object)(ScreenName)(ref val)).ToString(), StringComparison.OrdinalIgnoreCase) ? 1 : 0); } else { result = 1; } return (byte)result != 0; } catch { return false; } } } [HarmonyPatch(typeof(RelicDraftRewardData))] public static class RelicDraftRewardDataPatches { [HarmonyPrefix] [HarmonyPatch("PregenerateRelicRewards")] public static void PregenerateRelicRewards_Prefix(RelicDraftRewardData __instance) { ArtifactCapturer.OnRewardNodeNameChanged(((Object)__instance).name); } } [HarmonyPatch(typeof(RelicPoolHelper))] public static class RelicPoolHelperPatches { [HarmonyPostfix] [HarmonyPatch("GetNonStartingRelicsForClass")] public static void GetNonStartingRelicsForClass_Postfix(List __result) { ArtifactCapturer.OnArtifactsGenerated(__result); } [HarmonyPostfix] [HarmonyPatch("GetNonClassRelics")] public static void GetNonClassRelics_Postfix(List __result) { ArtifactCapturer.OnArtifactsGenerated(__result); } } [HarmonyPatch(typeof(RunSetupScreen))] public static class RunSetupScreenPatches { [HarmonyPrefix] [HarmonyPatch("ApplyScreenInput", new Type[] { typeof(CoreInputControlMapping), typeof(IGameUIComponent), typeof(Controls) })] public static bool ApplyScreenInput_Prefix(RunSetupScreen __instance, CoreInputControlMapping mapping, IGameUIComponent triggeredUI, Controls triggeredMappingID, ref bool __result) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) GameUISelectableButton seedExplorerFooterButton = ModRegistry.GetSeedExplorerFooterButton(__instance); if ((Object)(object)seedExplorerFooterButton != (Object)null && seedExplorerFooterButton.TryTrigger(mapping, triggeredUI, triggeredMappingID, false, false)) { __result = true; return false; } SeedExplorerDialog seedExplorerDialog = ModRegistry.GetSeedExplorerDialog(__instance); if ((Object)(object)seedExplorerDialog != (Object)null && seedExplorerDialog.ApplyScreenInput(mapping, triggeredUI, triggeredMappingID)) { __result = true; return false; } return true; } [HarmonyPrefix] [HarmonyPatch("Start")] public static bool Start_Prefix(RunSetupScreen __instance) { return true; } } [HarmonyPatch(typeof(SaveManager))] public static class SaveManagerPatches { [HarmonyPrefix] [HarmonyPatch("ResetRandomState")] public static void ResetRandomState_Prefix(SaveManager __instance) { if (SeedExplorer.Instance.ShouldOverrideSeed) { int forcedSeed = SeedExplorer.Instance.ForcedSeed; SaveData value = Traverse.Create((object)__instance).Property("ActiveSaveData", (object[])null).GetValue(); if (value != null) { ((BaseSaveData)value).SetSeed(forcedSeed); } SeedExplorer.Instance.ShouldOverrideSeed = false; } } [HarmonyPrefix] [HarmonyPatch("GenerateRelicRewardsAtDistance")] public static void GenerateRelicRewardsAtDistance_Prefix(int distance) { ArtifactCapturer.OnGenerationDistanceChanged(distance); } } internal static class UndoTurnDiagnosticPatches { internal static int? CurrentTurnCounter; internal static string CurrentCombatPhase; private static int ReadField(object obj, string name) where T : struct { try { T value = Traverse.Create(obj).Field(name).Value; if (value is int) { object obj2 = value; int result = (int)((obj2 is int) ? obj2 : null); if (true) { return result; } } if (value is long) { object obj3 = value; long num = (long)((obj3 is long) ? obj3 : null); if (true) { return (int)num; } } return Convert.ToInt32(value); } catch { return -2; } } internal static int GetReplayCount(ReplayData data) { if (data == null) { return -1; } try { return Traverse.Create((object)data).Field>("replayEntries").Value?.Count ?? (-1); } catch { return -1; } } internal static int GetMarkerLastEndTurn(ReplayData data) { return (data == null) ? (-2) : ReadField(data, "lastEndTurnEntryIndex"); } internal static int GetMarkerBattleBegin(ReplayData data) { return (data == null) ? (-2) : ReadField(data, "battleBeginEntryIndex"); } } [HarmonyPatch(typeof(ReplayData))] internal static class ReplayDataDiagnosticPatches { [HarmonyPostfix] [HarmonyPatch("SetLastEndTurnEntryIndex")] public static void SetLastEndTurnEntryIndex_Postfix(ReplayData __instance, ref int __result) { int replayCount = UndoTurnDiagnosticPatches.GetReplayCount(__instance); int markerBattleBegin = UndoTurnDiagnosticPatches.GetMarkerBattleBegin(__instance); Plugin.Log("[MTSE-Undo] SetLastEndTurnEntryIndex returned=" + __result.ToString(CultureInfo.InvariantCulture) + " replayCount=" + replayCount.ToString(CultureInfo.InvariantCulture) + " battleBegin=" + markerBattleBegin.ToString(CultureInfo.InvariantCulture) + " turn=" + (UndoTurnDiagnosticPatches.CurrentTurnCounter?.ToString(CultureInfo.InvariantCulture) ?? "?") + " phase=" + (UndoTurnDiagnosticPatches.CurrentCombatPhase ?? "?")); } [HarmonyPostfix] [HarmonyPatch("AddToReplay")] public static void AddToReplay_Postfix(ReplayData __instance, ReplayEntryType entryType, bool isInBattle) { if (isInBattle) { int replayCount = UndoTurnDiagnosticPatches.GetReplayCount(__instance); int markerLastEndTurn = UndoTurnDiagnosticPatches.GetMarkerLastEndTurn(__instance); int markerBattleBegin = UndoTurnDiagnosticPatches.GetMarkerBattleBegin(__instance); Plugin.Log("[MTSE-Undo] AddToReplay entry=" + ((object)(ReplayEntryType)(ref entryType)).ToString() + " newCount=" + replayCount.ToString(CultureInfo.InvariantCulture) + " lastEndTurn=" + markerLastEndTurn.ToString(CultureInfo.InvariantCulture) + " battleBegin=" + markerBattleBegin.ToString(CultureInfo.InvariantCulture) + " turn=" + (UndoTurnDiagnosticPatches.CurrentTurnCounter?.ToString(CultureInfo.InvariantCulture) ?? "?") + " phase=" + (UndoTurnDiagnosticPatches.CurrentCombatPhase ?? "?")); } } [HarmonyPrefix] [HarmonyPatch("RevertLastReplayEntry")] public static void RevertLastReplayEntry_Prefix(ReplayData __instance) { int replayCount = UndoTurnDiagnosticPatches.GetReplayCount(__instance); int markerLastEndTurn = UndoTurnDiagnosticPatches.GetMarkerLastEndTurn(__instance); int markerBattleBegin = UndoTurnDiagnosticPatches.GetMarkerBattleBegin(__instance); Plugin.Log("[MTSE-Undo] RevertLastReplayEntry before count=" + replayCount.ToString(CultureInfo.InvariantCulture) + " lastEndTurn=" + markerLastEndTurn.ToString(CultureInfo.InvariantCulture) + " battleBegin=" + markerBattleBegin.ToString(CultureInfo.InvariantCulture)); } } [HarmonyPatch(typeof(CombatManager))] internal static class CombatManagerDiagnosticPatches { [HarmonyPostfix] [HarmonyPatch("SetCombatPhase")] public static void SetCombatPhase_Postfix(CombatManager __instance, Phase newPhase) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 try { int value = (((Object)(object)__instance != (Object)null) ? __instance.GetTurnCount() : (-1)); UndoTurnDiagnosticPatches.CurrentTurnCounter = value; UndoTurnDiagnosticPatches.CurrentCombatPhase = ((object)(Phase)(ref newPhase)).ToString(); if ((int)newPhase == 3) { int lastPlayerActionPhaseReplayIndex = UndoTurnPatches.LastPlayerActionPhaseReplayIndex; int lastPlayerActionPhaseReplayIndex2 = -1; try { AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); IExternalAccess val2 = (((Object)(object)val != (Object)null) ? val.GetReplayData() : null); if (val2 != null) { lastPlayerActionPhaseReplayIndex2 = val2.GetReplayEntries().Count - 1; } } catch (Exception ex) { Plugin.LogError("[MTSE-Undo] Failed to capture player-action marker: " + ex.Message); } UndoTurnPatches.LastPlayerActionPhaseReplayIndex = lastPlayerActionPhaseReplayIndex2; Plugin.Log("[MTSE-Undo] PlayerActionPhase marker updated turn=" + value.ToString(CultureInfo.InvariantCulture) + " from=" + lastPlayerActionPhaseReplayIndex.ToString(CultureInfo.InvariantCulture) + " to=" + lastPlayerActionPhaseReplayIndex2.ToString(CultureInfo.InvariantCulture)); } Plugin.Log("[MTSE-Undo] SetCombatPhase newPhase=" + ((object)(Phase)(ref newPhase)).ToString() + " turn=" + value.ToString(CultureInfo.InvariantCulture)); } catch (Exception ex2) { Plugin.LogError("[MTSE-Undo] SetCombatPhase_Postfix failed: " + ex2.Message); } } [HarmonyPostfix] [HarmonyPatch("StopCombat")] public static void StopCombat_Postfix() { UndoTurnPatches.LastPlayerActionPhaseReplayIndex = -1; Plugin.Log("[MTSE-Undo] StopCombat — reset player-action marker to -1"); } } [HarmonyPatch(typeof(ReplayData))] public static class UndoTurnPatches { internal static int LastPlayerActionPhaseReplayIndex = -1; public static bool DisableFix { get; set; } [HarmonyPostfix] [HarmonyPatch("GetNumUndoEntriesToRemoveFromEnd")] public static void GetNumUndoEntriesToRemoveFromEnd_Postfix(ReplayData __instance, ref int __result) { int num = __result; int value = Traverse.Create((object)__instance).Field("lastEndTurnEntryIndex").Value; int value2 = Traverse.Create((object)__instance).Field("battleBeginEntryIndex").Value; int num2 = Traverse.Create((object)__instance).Field>("replayEntries").Value?.Count ?? (-1); int lastPlayerActionPhaseReplayIndex = LastPlayerActionPhaseReplayIndex; string text; if (value >= 0) { text = "lastEndTurn"; } else if (value2 >= 0) { text = "battleBegin"; if (!DisableFix) { __result = Math.Max(0, __result - 1); } } else { text = "noMarker"; } if (!DisableFix && lastPlayerActionPhaseReplayIndex >= 0 && num2 >= 0) { int num3 = Math.Max(0, num2 - lastPlayerActionPhaseReplayIndex - 1); if (num3 != __result) { Plugin.Log("[MTSE-Undo] GetNumUndoEntriesToRemoveFromEnd OVERRIDE branch=" + text + " replayCount=" + num2.ToString(CultureInfo.InvariantCulture) + " gameMarker_lastEndTurn=" + value.ToString(CultureInfo.InvariantCulture) + " gameMarker_battleBegin=" + value2.ToString(CultureInfo.InvariantCulture) + " ourMarker=" + lastPlayerActionPhaseReplayIndex.ToString(CultureInfo.InvariantCulture) + " original=" + num.ToString(CultureInfo.InvariantCulture) + " adjusted=" + num3.ToString(CultureInfo.InvariantCulture)); } __result = num3; } else { Plugin.Log("[MTSE-Undo] GetNumUndoEntriesToRemoveFromEnd branch=" + text + " replayCount=" + num2.ToString(CultureInfo.InvariantCulture) + " gameMarker_lastEndTurn=" + value.ToString(CultureInfo.InvariantCulture) + " gameMarker_battleBegin=" + value2.ToString(CultureInfo.InvariantCulture) + " ourMarker=" + lastPlayerActionPhaseReplayIndex.ToString(CultureInfo.InvariantCulture) + " original=" + num.ToString(CultureInfo.InvariantCulture) + " adjusted=" + __result.ToString(CultureInfo.InvariantCulture)); } } } [HarmonyPatch(typeof(SaveManager))] public static class UndoTurnSaveManagerPatches { [HarmonyPrefix] [HarmonyPatch("UndoTurn", new Type[] { typeof(bool) })] public static void UndoTurn_Prefix(SaveManager __instance, bool visible) { IExternalAccess val = ((__instance != null) ? __instance.GetReplayData() : null); int num = ((val != null) ? val.GetNumUndosUsedThisTurn() : (-1)); int num2 = (((Object)(object)__instance != (Object)null) ? __instance.GetNumUndosPerTurn() : (-1)); Plugin.Log("[MTSE-Undo] SaveManager.UndoTurn invoked visible=" + visible + " numUndosUsedThisTurn=" + num.ToString(CultureInfo.InvariantCulture) + " numUndosPerTurn=" + num2.ToString(CultureInfo.InvariantCulture) + " ourMarker=" + UndoTurnPatches.LastPlayerActionPhaseReplayIndex.ToString(CultureInfo.InvariantCulture)); } } [HarmonyPatch(typeof(UnityMainThreadRunner))] public static class UnityMainThreadRunnerPatches { [HarmonyPostfix] [HarmonyPatch("Update")] public static void Update_Postfix() { AutomationBridge.DrainActiveMainThreadQueue(); } } } namespace MTSeedExplorer.Core { public class ArtifactCapturer : IDisposable { public static ArtifactCapturer Instance { get; set; } = new ArtifactCapturer(); private bool IsCaptureRequested { get; set; } = false; private int CurrentRing { get; set; } = 0; private bool IsRingOkayToCapture { get; set; } = false; private string CurrentRewardNodeName { get; set; } = string.Empty; private bool IsNodeOkayToCapture { get; set; } = false; public List Artifacts { get; private set; } = new List(); public static ArtifactCapturer StartCapture() { ArtifactCapturer artifactCapturer = new ArtifactCapturer(); artifactCapturer.startCaptureInternal(); Instance = artifactCapturer; return artifactCapturer; } private void startCaptureInternal() { IsCaptureRequested = true; } public static void OnGenerationDistanceChanged(int x) { Instance.onGenerationDistanceChanged(x); } private void onGenerationDistanceChanged(int x) { CurrentRing = x; if (IsCaptureRequested && CurrentRing == 0) { IsRingOkayToCapture = true; } if (CurrentRing != 0) { IsRingOkayToCapture = false; } } public static void OnRewardNodeNameChanged(string s) { Instance.onRewardNodeNameChanged(s); } private void onRewardNodeNameChanged(string s) { CurrentRewardNodeName = s; if (IsCaptureRequested && CurrentRewardNodeName == "BlessingDraftReward") { IsNodeOkayToCapture = true; } if (CurrentRewardNodeName != "BlessingDraftReward") { IsNodeOkayToCapture = false; } } public static void OnArtifactsGenerated(List l) { Instance.onArtifactsGenerated(l); } private void onArtifactsGenerated(List l) { if (IsRingOkayToCapture && IsNodeOkayToCapture) { Artifacts.AddRange(l); } } public void Dispose() { IsCaptureRequested = false; IsRingOkayToCapture = false; IsNodeOkayToCapture = false; } } internal class ModRegistry { private static readonly ConditionalWeakTable _seedExplorerFooterButtonMap = new ConditionalWeakTable(); private static readonly ConditionalWeakTable _seedExplorerDialogMap = new ConditionalWeakTable(); private static long _seedExplorerDialogRegistrationCount; internal static long SeedExplorerDialogRegistrationCount => Interlocked.Read(ref _seedExplorerDialogRegistrationCount); internal static void RegisterSeedExplorerFooterButton(RunSetupScreen screen, GameUISelectableButton button) { _seedExplorerFooterButtonMap.Add(screen, button); } internal static GameUISelectableButton GetSeedExplorerFooterButton(RunSetupScreen screen) { if (_seedExplorerFooterButtonMap.TryGetValue(screen, out var value)) { return value; } return null; } internal static void RegisterSeedExplorerDialog(RunSetupScreen screen, SeedExplorerDialog dialog) { _seedExplorerDialogMap.Add(screen, dialog); Interlocked.Increment(ref _seedExplorerDialogRegistrationCount); } internal static SeedExplorerDialog GetSeedExplorerDialog(RunSetupScreen screen) { if (_seedExplorerDialogMap.TryGetValue(screen, out var value)) { return value; } return null; } } public sealed class RunSetupContext { public string MainClassId { get; } public int MainChampionIndex { get; } public string SubClassId { get; } public int SubChampionIndex { get; } public string PyreHeartId { get; } public int AscensionLevel { get; } public bool AreMutatorsEnabled { get; } public IReadOnlyList MutatorIds { get; } public IReadOnlyList EnabledDlcs { get; } public RunType RunType { get; } public string Signature { get; } private RunSetupContext(string mainClassId, int mainChampionIndex, string subClassId, int subChampionIndex, string pyreHeartId, int ascensionLevel, bool areMutatorsEnabled, IReadOnlyList mutatorIds, IReadOnlyList enabledDlcs, RunType runType) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) MainClassId = mainClassId ?? ""; MainChampionIndex = mainChampionIndex; SubClassId = subClassId ?? ""; SubChampionIndex = subChampionIndex; PyreHeartId = pyreHeartId ?? ""; AscensionLevel = ascensionLevel; AreMutatorsEnabled = areMutatorsEnabled; MutatorIds = mutatorIds ?? Array.Empty(); EnabledDlcs = enabledDlcs ?? Array.Empty(); RunType = runType; Signature = ComputeSignature(); } public static RunSetupContext TryCapture(RunSetupScreen runSetupScreen) { //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)runSetupScreen == (Object)null) { return null; } try { Traverse val = Traverse.Create((object)runSetupScreen); RunSetupClassLevelInfoUI value = val.Field("mainClassInfo").GetValue(); RunSetupClassLevelInfoUI value2 = val.Field("subClassInfo").GetValue(); PyreHeartInfoUI value3 = val.Field("pyreHeartInfo").GetValue(); CovenantSelectionUI value4 = val.Field("covenantSelectionUI").GetValue(); if ((Object)(object)value == (Object)null || (Object)(object)value2 == (Object)null || (Object)(object)value3 == (Object)null || (Object)(object)value4 == (Object)null) { return null; } bool value5 = val.Field("areMutatorsEnabled").GetValue(); List source = val.Field("mutatorIds").GetValue>() ?? new List(); List list = (value5 ? source.Where((string x) => !string.IsNullOrEmpty(x)).OrderBy((string x) => x, StringComparer.Ordinal).ToList() : new List()); string mainClassId = ((!string.IsNullOrEmpty(value.RandomId)) ? value.RandomId : "random"); if ((Object)(object)value.ClassData != (Object)null) { mainClassId = ((GameData)value.ClassData).GetID(); } string subClassId = ((!string.IsNullOrEmpty(value2.RandomId)) ? value2.RandomId : "random"); if ((Object)(object)value2.ClassData != (Object)null) { subClassId = ((GameData)value2.ClassData).GetID(); } string pyreHeartId = (((Object)(object)value3.PyreHeartCharacterData != (Object)null) ? ((GameData)value3.PyreHeartCharacterData).GetID() : "random"); int currentLevel = value4.CurrentLevel; List enabledDlcs = new List(); try { SaveManager val2 = (((Object)(object)AllGameManagers.Instance != (Object)null) ? AllGameManagers.Instance.GetSaveManager() : null); if ((Object)(object)val2 != (Object)null) { IReadOnlyList installedAndMetagameEnabledDLCs = val2.GetInstalledAndMetagameEnabledDLCs(); if (installedAndMetagameEnabledDLCs != null) { enabledDlcs = installedAndMetagameEnabledDLCs.Select((DLC d) => ((object)(DLC)(ref d)).ToString()).OrderBy((string x) => x, StringComparer.Ordinal).ToList(); } } } catch { } RunType runType = (RunType)((list.Count <= 0) ? 1 : 3); return new RunSetupContext(mainClassId, value.ChampionIndex, subClassId, value2.ChampionIndex, pyreHeartId, currentLevel, value5, list, enabledDlcs, runType); } catch { return null; } } public StartingConditions ToStartingConditions(SaveManager saveManager) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) StartingConditions result = default(StartingConditions); ((StartingConditions)(ref result)).SetMainClass(MainClassId, MainChampionIndex, ""); ((StartingConditions)(ref result)).SetSubClass(SubClassId, SubChampionIndex, ""); ((StartingConditions)(ref result)).SetClassLevelsAndUnlocks(saveManager.CreateStartingConditionClassLevelsAndUnlocks()); ((StartingConditions)(ref result)).SetPyreCharacterId(PyreHeartId, (PyreHeartId == "random") ? "random" : ""); ((StartingConditions)(ref result)).SetAscensionLevel(AscensionLevel); if (AreMutatorsEnabled && MutatorIds.Count > 0) { ((StartingConditions)(ref result)).SetMutatorIds((IReadOnlyList)MutatorIds.ToList()); } try { IReadOnlyList installedAndMetagameEnabledDLCs = saveManager.GetInstalledAndMetagameEnabledDLCs(); if (installedAndMetagameEnabledDLCs != null) { ((StartingConditions)(ref result)).SetEnabledDlcs(installedAndMetagameEnabledDLCs); } } catch { } return result; } private string ComputeSignature() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(96); stringBuilder.Append(RunType).Append('|'); stringBuilder.Append(MainClassId).Append(':').Append(MainChampionIndex) .Append('|'); stringBuilder.Append(SubClassId).Append(':').Append(SubChampionIndex) .Append('|'); stringBuilder.Append(PyreHeartId).Append('|'); stringBuilder.Append("asc=").Append(AscensionLevel).Append('|'); stringBuilder.Append("mut=").Append(AreMutatorsEnabled ? "on" : "off").Append(':'); stringBuilder.Append(string.Join(",", MutatorIds)).Append('|'); stringBuilder.Append("dlc=").Append(string.Join(",", EnabledDlcs)); return stringBuilder.ToString(); } public override string ToString() { return Signature; } public override bool Equals(object obj) { return obj is RunSetupContext runSetupContext && Signature == runSetupContext.Signature; } public override int GetHashCode() { return Signature.GetHashCode(); } } public class SeedExplorer { public class SeedResult { public int Seed; public string Card1; public string Card2; public string Card3; public string Artifact1; public string Artifact2; public string Upgrade1; public string Upgrade2; } public class ActiveRunOptionsSnapshot { public bool Ready { get; set; } public string Reason { get; set; } = ""; public SeedResult SelectedRow { get; set; } public SeedResult Options { get; set; } public List Cards { get; set; } = new List(); public List Artifacts { get; set; } = new List(); public List Upgrades { get; set; } = new List(); public static ActiveRunOptionsSnapshot NotReady(string reason) { return new ActiveRunOptionsSnapshot { Ready = false, Reason = reason }; } } public class SeedFilter { public string PrimaryCard { get; set; } = null; public string SecondaryCard { get; set; } = null; public string UnitCard { get; set; } = null; public string Artifact { get; set; } = null; public string Upgrade { get; set; } = null; } public enum FilterType { PrimaryCard, SecondaryCard, UnitCard, Artifact, Upgrade } public enum PreloadStatus { Idle, Populating, Generating, Ready, Faulted } private Func currentFilterPredicate = (SeedResult _) => true; private DateTime searchStartedUtc; public Action OnStartingArtifactsGenerated = delegate { }; public SeedFilter Filter { get; set; } = new SeedFilter(); public static SeedExplorer Instance => GetActiveInstance(); public static Dictionary Instances { get; set; } = new Dictionary { { "default", new SeedExplorer() } }; public static string ActiveInstanceKey { get; set; } = "default"; private SaveManager saveManager => AllGameManagers.Instance.GetSaveManager(); private SaveData activeSaveData => Traverse.Create((object)saveManager).Property("ActiveSaveData", (object[])null).GetValue(); public bool ShouldOverrideSeed { get; set; } public bool ShouldCaptureStartingCardPool { get; set; } public bool ShouldCaptureStartingArtifactsPool { get; private set; } public bool ShouldCaptureStartingArtifactsPregenId { get; set; } public int ForcedSeed { get; set; } public List SeedResults { get; set; } = new List(); public List SeedResultsFiltered { get; set; } = new List(); public List PrimaryCardPool { get; set; } = new List(); public List SecondaryCardPool { get; set; } = new List(); public List UnitCardPool { get; set; } = new List(); public List ArtifactPool { get; set; } = new List(); public List UpgradePool { get; set; } = new List(); public SeedResult SelectedSeedResult { get; private set; } public PreloadStatus Status { get; private set; } = PreloadStatus.Idle; public int TargetSeedCount { get; private set; } public string ContextSignature { get; private set; } public string LastError { get; private set; } public long PreloadVersion { get; private set; } public bool IsSearching { get; private set; } internal RunSetupContext PreloadContext { get; private set; } private string startingArtifactsPregenId { get; set; } private List> cardPools { get; set; } = new List>(); public List UpdateFilter(FilterType filterType, string s) { if (s == "") { s = null; } switch (filterType) { case FilterType.PrimaryCard: Filter.PrimaryCard = s; break; case FilterType.SecondaryCard: Filter.SecondaryCard = s; break; case FilterType.UnitCard: Filter.UnitCard = s; break; case FilterType.Artifact: Filter.Artifact = s; break; case FilterType.Upgrade: Filter.Upgrade = s; break; } currentFilterPredicate = BuildFilterPredicate(); SeedResultsFiltered = SeedResults.Where(currentFilterPredicate).ToList(); if (SeedResultsFiltered.Count == 0 && HasAnyFilter()) { IsSearching = true; searchStartedUtc = DateTime.UtcNow; if (Status == PreloadStatus.Ready) { Status = PreloadStatus.Generating; } while (IsSearching && SeedResultsFiltered.Count == 0 && Status != PreloadStatus.Faulted) { Tick(); } } else { IsSearching = false; } return SeedResultsFiltered; } private bool HasAnyFilter() { return Filter.PrimaryCard != null || Filter.SecondaryCard != null || Filter.UnitCard != null || Filter.Artifact != null || Filter.Upgrade != null; } private Func BuildFilterPredicate() { List> list = new List>(); if (Filter.PrimaryCard != null) { list.Add((SeedResult x) => x.Card1 == Filter.PrimaryCard); } if (Filter.SecondaryCard != null) { list.Add((SeedResult x) => x.Card2 == Filter.SecondaryCard); } if (Filter.UnitCard != null) { list.Add((SeedResult x) => x.Card3 == Filter.UnitCard); } if (Filter.Artifact != null) { list.Add((SeedResult x) => x.Artifact1 == Filter.Artifact || x.Artifact2 == Filter.Artifact); } if (Filter.Upgrade != null) { list.Add((SeedResult x) => x.Upgrade1 == Filter.Upgrade || x.Upgrade2 == Filter.Upgrade); } return list.Aggregate, Func>((SeedResult _) => true, (Func prev, Func next) => (SeedResult x) => prev(x) && next(x)); } public static SeedExplorer GetActiveInstance() { return Instances[ActiveInstanceKey]; } public static void ResetAllInstances() { Instances = new Dictionary { { "default", new SeedExplorer() } }; ActiveInstanceKey = "default"; } public static SeedExplorer GetOrCreateInstance(string key) { if (!Instances.TryGetValue(key, out var value)) { Instances.Add(key, value = new SeedExplorer()); } ActiveInstanceKey = key; return value; } public void OnStartingCardPoolGenerated(List cardPool) { cardPools.Add(cardPool); } private StartingConditions GetStartingConditions() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) RunSetupContext runSetupContext = PreloadContext; if (runSetupContext == null) { RunSetupScreen runSetupScreen = (RunSetupScreen)(((Object)(object)AllGameManagers.Instance != (Object)null && (Object)(object)AllGameManagers.Instance.GetScreenManager() != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); runSetupContext = RunSetupContext.TryCapture(runSetupScreen); } if (runSetupContext == null) { throw new InvalidOperationException("RunSetupScreen state was not available for seed simulation."); } return runSetupContext.ToStartingConditions(saveManager); } private void PopulatePossibilities() { try { ShouldCaptureStartingCardPool = true; ShouldCaptureStartingArtifactsPool = true; using ArtifactCapturer artifactCapturer = ArtifactCapturer.StartCapture(); SimulateGameStart(); ArtifactPool = artifactCapturer.Artifacts.Select((CollectableRelicData x) => ((RelicData)x).Cheat_GetNameEnglish()).ToList(); CardState val = saveManager.GetDeckState().Find((CardState c) => c.IsChampionCard()); CardUpgradeTreeData upgradeTree = ChampionUpgradeRewardData.GetUpgradeTree(val.GetSpawnCharacterData(), saveManager.GetBalanceData()); UpgradePool = (from x in upgradeTree.GetUpgradeTrees() select x.GetCardUpgrades().First().Cheat_GetNameEnglish()).ToList(); PrimaryCardPool = cardPools[0].Select((CardData x) => x.Cheat_GetNameEnglish()).ToList(); SecondaryCardPool = cardPools[1].Select((CardData x) => x.Cheat_GetNameEnglish()).ToList(); UnitCardPool = (from x in cardPools[2].Union(cardPools[3]) select x.Cheat_GetNameEnglish()).ToList(); } finally { ShouldCaptureStartingArtifactsPool = false; ShouldCaptureStartingCardPool = false; } } public void BeginPreload(RunSetupContext context, int targetSeedCount) { if (context == null) { throw new ArgumentNullException("context"); } if (targetSeedCount < 1) { targetSeedCount = 1; } if (PreloadContext != null && PreloadContext.Signature == context.Signature) { if (TargetSeedCount < targetSeedCount) { TargetSeedCount = targetSeedCount; } if (Status == PreloadStatus.Idle || Status == PreloadStatus.Faulted) { Status = PreloadStatus.Populating; } else if (Status == PreloadStatus.Ready && SeedResults.Count < TargetSeedCount) { Status = PreloadStatus.Generating; } } else { ResetForNewContext(context, targetSeedCount); } } private void ResetForNewContext(RunSetupContext context, int targetSeedCount) { PreloadContext = context; ContextSignature = context.Signature; TargetSeedCount = targetSeedCount; SeedResults = new List(); SeedResultsFiltered = new List(); cardPools = new List>(); PrimaryCardPool = new List(); SecondaryCardPool = new List(); UnitCardPool = new List(); ArtifactPool = new List(); UpgradePool = new List(); Filter = new SeedFilter(); currentFilterPredicate = (SeedResult _) => true; IsSearching = false; LastError = null; Status = PreloadStatus.Populating; PreloadVersion++; } public void Tick() { try { switch (Status) { case PreloadStatus.Populating: PopulatePossibilities(); Status = PreloadStatus.Generating; PreloadVersion++; break; case PreloadStatus.Generating: { if (SeedResults.Count >= TargetSeedCount && !IsSearching) { Status = PreloadStatus.Ready; PreloadVersion++; break; } ForcedSeed = Random.Range(0, int.MaxValue); SeedResult item = ExploreSeed(ForcedSeed); SeedResults.Add(item); SeedResultsFiltered = SeedResults.Where(currentFilterPredicate).ToList(); PreloadVersion++; bool flag = IsSearching && SeedResultsFiltered.Count > 0; bool flag2 = IsSearching && (DateTime.UtcNow - searchStartedUtc).TotalSeconds > (double)Settings.SearchTimeoutSeconds.Value; if (flag || flag2) { if (flag2 && !flag) { Plugin.Log($"Couldn't find matching seed in {Settings.SearchTimeoutSeconds.Value} seconds."); } IsSearching = false; } if (SeedResults.Count >= TargetSeedCount && !IsSearching) { Status = PreloadStatus.Ready; } break; } case PreloadStatus.Ready: if (IsSearching) { Status = PreloadStatus.Generating; } break; } } catch (Exception ex) { LastError = ex.Message; Status = PreloadStatus.Faulted; Plugin.LogError("Seed preload failure: " + ex); } } public void ExploreSeeds() { if (PreloadContext == null) { RunSetupScreen runSetupScreen = (RunSetupScreen)(((Object)(object)AllGameManagers.Instance != (Object)null && (Object)(object)AllGameManagers.Instance.GetScreenManager() != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); RunSetupContext runSetupContext = RunSetupContext.TryCapture(runSetupScreen); if (runSetupContext == null) { throw new InvalidOperationException("RunSetupScreen state was not available for seed simulation."); } ResetForNewContext(runSetupContext, Math.Max(1, Settings.InitialSeedCount.Value)); } int num = Math.Max(1, Settings.InitialSeedCount.Value); if (Status == PreloadStatus.Populating) { PopulatePossibilities(); Status = PreloadStatus.Generating; } while (SeedResults.Count < num) { ForcedSeed = Random.Range(0, int.MaxValue); SeedResults.Add(ExploreSeed(ForcedSeed)); } SeedResultsFiltered = SeedResults.ToList(); Status = PreloadStatus.Ready; PreloadVersion++; } private SeedResult ExploreSeed(int seed) { try { ShouldOverrideSeed = true; StartCapturingStartingArtifactsPregenId(stopAfterCapture: false); SimulateGameStart(); List list = SimulateChampionUpgrade(); List startOfRunShowcaseCards = saveManager.StartOfRunShowcaseCards; List source = list; List list2 = startOfRunShowcaseCards.Select((CardData c) => c.Cheat_GetNameEnglish()).ToList(); List startingArtifactNames = GetStartingArtifactNames(startingArtifactsPregenId); List list3 = source.Select((CardUpgradeData u) => u.Cheat_GetNameEnglish()).ToList(); if (Settings.EnableDebugLogging.Value) { string message = seed + ":" + string.Join(',', list2.Union(startingArtifactNames).Union(list3)); Plugin.Log(message); } return new SeedResult { Seed = seed, Card1 = list2[0], Card2 = list2[2], Card3 = list2[4], Artifact1 = startingArtifactNames[0], Artifact2 = startingArtifactNames[1], Upgrade1 = list3[0], Upgrade2 = list3[1] }; } catch (Exception ex) { Plugin.Logger.LogError((object)ex); throw ex; } finally { ShouldCaptureStartingArtifactsPregenId = false; } } private List SimulateChampionUpgrade() { RewardState val = ((IEnumerable)Traverse.Create((object)activeSaveData).Field("rewardStates").GetValue>()).FirstOrDefault((Func)((RewardState r) => (Object)(object)r.RewardData != (Object)null && ((Object)r.RewardData).name == "ChampionUpgradeReward")); if (val == null) { return new List(); } RandomManager.ResetRng((RngId)10, RandomManager.GetMurmurHash(((GameData)val.RewardData).GetID() + "rewardMap")); CardState val2 = saveManager.GetDeckState().Find((CardState c) => c.IsChampionCard()); if (val2 == null) { return new List(); } CardUpgradeTreeData upgradeTree = ChampionUpgradeRewardData.GetUpgradeTree(val2.GetSpawnCharacterData(), saveManager.GetBalanceData()); List randomChoices = upgradeTree.GetRandomChoices(2, val2, false); return randomChoices.ToList(); } private void SimulateGameStart() { //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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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_0236: 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_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Invalid comparison between Unknown and I4 List value = new List(5); List value2 = new List(5); GameStateManager gameStateManager = AllGameManagers.Instance.GetGameStateManager(); RelicManager relicManager = AllGameManagers.Instance.GetRelicManager(); StartingConditions startingConditions = GetStartingConditions(); ClassData val = saveManager.GetAllGameData().FindClassData(((StartingConditions)(ref startingConditions)).ClassId); ClassData val2 = saveManager.GetAllGameData().FindClassData(((StartingConditions)(ref startingConditions)).SubclassId); string text = (((Object)(object)val != (Object)null) ? val.GetTitle() : null) ?? "RANDOM"; string text2 = (((Object)(object)val2 != (Object)null) ? val2.GetTitle() : null) ?? "RANDOM"; saveManager.ResetSave((RunType?)(RunType)1, "", false, false); saveManager.SetActiveRunType((RunType)1); saveManager.SetClassLevelsAndUnlocks(((StartingConditions)(ref startingConditions)).GetUnlockInfoCopy()); saveManager.SetSpChallenge(((StartingConditions)(ref startingConditions)).SpChallengeId); saveManager.AddMutatorsById(((StartingConditions)(ref startingConditions)).Mutators); saveManager.LoadClassesFromStartingConditions(startingConditions, false); saveManager.SetAscensionLevel(((StartingConditions)(ref startingConditions)).AscensionLevel); saveManager.SetRunDLCs(((StartingConditions)(ref startingConditions)).EnabledDlcs); saveManager.SetActiveSavePyreCharacter(((StartingConditions)(ref startingConditions)).PyreCharacterId, ((StartingConditions)(ref startingConditions)).IsRandomPyreHeart ? "random" : "", false); saveManager.SetIsFtueRun(false); RunState runState = saveManager.GetRunState(); RunData runData = saveManager.GetRunData(); List list = new List(); list.AddRange((IEnumerable)saveManager.GetCovenants()); list.AddRange((IEnumerable)saveManager.GetMutators()); List collection = Traverse.Create((object)saveManager).Method("GetActiveSavePyreArtifactStates", Array.Empty()).GetValue>() .ToList(); list.AddRange((IEnumerable)collection); SetupData val3 = default(SetupData); val3.loopIndex = (saveManager.IsEndlessRun ? (runState.GetLoopIndex() + 1) : 0); val3.runData = runData; val3.covenantsAndMutators = list; val3.enabledDlcs = new List(saveManager.GetStartingConditions().GetEnabledDlcs()); SetupData val4 = val3; runState.Setup(val4); if (!saveManager.IsEndlessRun && (int)relicManager.GetShouldAddAlliedChampionCardToStartingDeck() > 0) { saveManager.AddCardToDeck(saveManager.GetSubClass().GetChampionCard(saveManager.GetSubChampionIndex()), (CardStateModifiers)null, false, 0, false, false, true, true, true); } if (!saveManager.IsEndlessRun) { runState.AddCardDraftRarityDataToRun(runData.GetCardDraftRarityData()); relicManager.ApplyStartOfRunRelicEffects(ref value, ref value2); Traverse.Create((object)saveManager).Field("startOfRunShowcaseCards").SetValue((object)value); Traverse.Create((object)saveManager).Field("startOfRunRewards").SetValue((object)value2); Traverse.Create((object)saveManager).Method("SetUnlockProgressAtStartOfRun", Array.Empty()).GetValue(); } saveManager.NeedToShowRunOpeningInfo = true; saveManager.NeedToShowRunOpeningDrafts = true; saveManager.NeedToShowOffMutators = saveManager.GetMutatorCount() > 0; activeSaveData.SetEndlessStartRunDraftCompleted(false); saveManager.SetupNodes(); ChampionUpgradeRewardData startingChampionUpgradeRewardData = runData.GetStartingChampionUpgradeRewardData(); if (startingChampionUpgradeRewardData != null) { startingChampionUpgradeRewardData.ApplyStartingUpgradesFromPoolToChampion(saveManager); } RandomManager.AdvanceToNextNode(); activeSaveData.GenerateInscryptionEventPath(); } internal void StartRun(int i) { if (i < 0 || i >= SeedResultsFiltered.Count) { throw new ArgumentOutOfRangeException("i", $"Seed result index {i} was outside the filtered result range."); } SelectedSeedResult = SeedResultsFiltered[i]; StartCapturingStartingArtifactsPregenId(stopAfterCapture: true); ShouldOverrideSeed = true; int seed = SelectedSeedResult.Seed; ForcedSeed = seed; } internal ActiveRunOptionsSnapshot GetActiveRunOptionsSnapshot() { if ((Object)(object)AllGameManagers.Instance == (Object)null) { return ActiveRunOptionsSnapshot.NotReady("AllGameManagers was not available."); } SaveManager val = AllGameManagers.Instance.GetSaveManager(); if ((Object)(object)val == (Object)null) { return ActiveRunOptionsSnapshot.NotReady("SaveManager was not available."); } List list = ((val.StartOfRunShowcaseCards != null) ? (from c in val.StartOfRunShowcaseCards where (Object)(object)c != (Object)null select c.Cheat_GetNameEnglish()).ToList() : new List()); if (list.Count < 5) { return ActiveRunOptionsSnapshot.NotReady("Start-of-run card options were not ready."); } List startingArtifactNames = GetStartingArtifactNames(startingArtifactsPregenId); if (startingArtifactNames.Count < 2) { string reason = (string.IsNullOrEmpty(startingArtifactsPregenId) ? "Starting artifact reward id was not captured." : "Starting artifact options were not ready."); return ActiveRunOptionsSnapshot.NotReady(reason); } List list2 = (from u in SimulateChampionUpgrade() where (Object)(object)u != (Object)null select u.Cheat_GetNameEnglish()).ToList(); if (list2.Count < 2) { return ActiveRunOptionsSnapshot.NotReady("Champion upgrade options were not ready."); } return new ActiveRunOptionsSnapshot { Ready = true, SelectedRow = SelectedSeedResult, Options = new SeedResult { Seed = ((SelectedSeedResult != null) ? SelectedSeedResult.Seed : ForcedSeed), Card1 = list[0], Card2 = list[2], Card3 = list[4], Artifact1 = startingArtifactNames[0], Artifact2 = startingArtifactNames[1], Upgrade1 = list2[0], Upgrade2 = list2[1] }, Cards = list, Artifacts = startingArtifactNames, Upgrades = list2 }; } private void StartCapturingStartingArtifactsPregenId(bool stopAfterCapture) { startingArtifactsPregenId = ""; ShouldCaptureStartingArtifactsPregenId = true; OnStartingArtifactsGenerated = delegate(IRewardGiver giver, int distance, int branch, int index) { string value = TryGetStartingArtifactsPregenId(giver, distance); if (!string.IsNullOrEmpty(value)) { startingArtifactsPregenId = value; if (stopAfterCapture) { ShouldCaptureStartingArtifactsPregenId = false; } } }; } private static string TryGetStartingArtifactsPregenId(IRewardGiver giver, int distance) { if (distance != 0) { return ""; } RewardNodeData val = (RewardNodeData)(object)((giver is RewardNodeData) ? giver : null); if ((Object)(object)val == (Object)null || ((Object)val).name != "RewardNodeBlessingOnly") { return ""; } return val.GetRewardGiverID(); } private List GetStartingArtifactNames(string rewardGiverId) { if (string.IsNullOrEmpty(rewardGiverId)) { return new List(); } return (from a in activeSaveData.GetPregeneratedRelicRewards() where a.id.rewardGiverID == rewardGiverId select saveManager.GetAllGameData().FindCollectableRelicData(a.relicDataID) into a where (Object)(object)a != (Object)null select ((RelicData)a).Cheat_GetNameEnglish()).Take(2).ToList(); } } } namespace MTSeedExplorer.Automation { internal sealed class AutomationBridge : IDisposable { private sealed class MainThreadRequest { internal readonly Func Handler; internal readonly ManualResetEventSlim Completion = new ManualResetEventSlim(initialState: false); internal string Response; internal Exception Exception; internal MainThreadRequest(Func handler) { Handler = handler; } } private sealed class AutomationBridgeUpdater : MonoBehaviour { internal AutomationBridge Bridge { get; set; } private void Update() { Bridge?.DrainMainThreadQueue(); } } private static AutomationBridge activeBridge; private readonly ConcurrentQueue mainThreadRequests = new ConcurrentQueue(); private readonly TcpListener listener; private readonly Thread listenerThread; private readonly string artifactDirectory; private GameObject updaterObject; private volatile bool isDisposed; private int lastObservedFrame; private int listenerHeartbeat; private AutomationBridge(int port, string artifactDirectory) { this.artifactDirectory = artifactDirectory; listener = new TcpListener(IPAddress.Loopback, port); listenerThread = new Thread(ListenLoop) { IsBackground = true, Name = "MTSeedExplorer Automation Bridge" }; } internal static AutomationBridge TryStart() { if (!ShouldEnable()) { return null; } int port = ReadIntEnvironment("MTSE_AUTOMATION_PORT", Settings.AutomationBridgePort.Value); string value = Environment.GetEnvironmentVariable("MTSE_AUTOMATION_ARTIFACT_DIR"); if (string.IsNullOrWhiteSpace(value)) { value = Settings.AutomationArtifactDirectory.Value; } if (string.IsNullOrWhiteSpace(value)) { value = Environment.CurrentDirectory; } try { AutomationBridge automationBridge = new AutomationBridge(port, value); automationBridge.Start(); return automationBridge; } catch (Exception ex) { Plugin.LogError("Failed to start automation bridge: " + ex); return null; } } private static bool ShouldEnable() { string environmentVariable = Environment.GetEnvironmentVariable("MTSE_ENABLE_AUTOMATION"); if (!string.IsNullOrWhiteSpace(environmentVariable)) { return IsTruthy(environmentVariable); } return Settings.EnableAutomationBridge.Value; } private static bool IsTruthy(string value) { return value == "1" || value.Equals("true", StringComparison.OrdinalIgnoreCase) || value.Equals("yes", StringComparison.OrdinalIgnoreCase) || value.Equals("on", StringComparison.OrdinalIgnoreCase); } private static int ReadIntEnvironment(string name, int fallback) { string environmentVariable = Environment.GetEnvironmentVariable(name); if (int.TryParse(environmentVariable, NumberStyles.None, CultureInfo.InvariantCulture, out var result)) { return result; } return fallback; } private void Start() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown listener.Start(); listenerThread.Start(); activeBridge = this; updaterObject = new GameObject("MTSeedExplorer Automation Bridge Updater"); Object.DontDestroyOnLoad((Object)(object)updaterObject); updaterObject.AddComponent().Bridge = this; Plugin.Log($"Automation bridge listening on http://127.0.0.1:{((IPEndPoint)listener.LocalEndpoint).Port}/"); } internal static void DrainActiveMainThreadQueue() { activeBridge?.DrainMainThreadQueue(); } internal void DrainMainThreadQueue() { lastObservedFrame = Time.frameCount; MainThreadRequest result; while (mainThreadRequests.TryDequeue(out result)) { try { result.Response = result.Handler(); } catch (Exception exception) { result.Exception = exception; } finally { result.Completion.Set(); } } } private int BumpListenerHeartbeat() { return Interlocked.Increment(ref listenerHeartbeat); } private int GetReportedFrame() { int num = lastObservedFrame; return (num > 0) ? num : Interlocked.CompareExchange(ref listenerHeartbeat, 0, 0); } private void ListenLoop() { while (!isDisposed) { try { TcpClient client = listener.AcceptTcpClient(); ThreadPool.QueueUserWorkItem(delegate { HandleClient(client); }); } catch (SocketException) { if (!isDisposed) { Plugin.LogError("Automation bridge listener socket failed."); } } catch (ObjectDisposedException) { break; } } } private void HandleClient(TcpClient client) { using (client) { using NetworkStream stream = client.GetStream(); using StreamReader streamReader = new StreamReader(stream, Encoding.ASCII, detectEncodingFromByteOrderMarks: false, 1024, leaveOpen: true); try { string text = streamReader.ReadLine(); if (string.IsNullOrWhiteSpace(text)) { WriteResponse(stream, 400, JsonError("Empty request.")); return; } string[] array = text.Split(' '); if (array.Length < 2) { WriteResponse(stream, 400, JsonError("Malformed request line.")); return; } string value; do { value = streamReader.ReadLine(); } while (!string.IsNullOrEmpty(value)); Uri uri = new Uri("http://127.0.0.1" + array[1]); if (RouteRequiresPreload(uri.AbsolutePath)) { WaitForPreloadOnListenerThread(TimeSpan.FromSeconds(30.0)); } if (RouteRequiresDialog(uri.AbsolutePath)) { WaitForSeedExplorerDialogOnListenerThread(TimeSpan.FromSeconds(15.0)); } string json = (IsBackgroundSafeRoute(uri.AbsolutePath) ? HandleRoute(uri) : InvokeOnMainThread(() => HandleRoute(uri))); WriteResponse(stream, 200, json); } catch (Exception ex) { try { Plugin.LogError("Automation bridge handler failed: " + ex); WriteResponse(stream, 500, JsonError(ex.Message)); } catch (Exception ex2) { Plugin.LogError("Automation bridge failed to write error response: " + ex2.Message); } } } } private string InvokeOnMainThread(Func handler) { if ((Object)(object)ThreadingHelper.Instance != (Object)null) { string response = null; Exception exception = null; ThreadingHelper.Instance.StartSyncInvoke((Action)delegate { try { response = handler(); } catch (Exception ex) { exception = ex; } }); if (exception != null) { throw exception; } return response; } MainThreadRequest mainThreadRequest = new MainThreadRequest(handler); mainThreadRequests.Enqueue(mainThreadRequest); if (!mainThreadRequest.Completion.Wait(TimeSpan.FromSeconds(15.0))) { throw new TimeoutException("Timed out waiting for Unity main thread."); } if (mainThreadRequest.Exception != null) { throw mainThreadRequest.Exception; } return mainThreadRequest.Response; } private string HandleRoute(Uri uri) { switch (uri.AbsolutePath.ToLowerInvariant()) { case "/health": return HealthJson(); case "/status": return StatusJson(); case "/objects": return ObjectsJson(uri); case "/screenshot": return ScreenshotJson(uri); case "/runsetup/state": return RunSetupSeedExplorerStateJson(); case "/runsetup/show": return ShowRunSetupJson(); case "/runsetup/click-choose-seed": return ClickChooseSeedJson(); case "/runsetup/dropdown/click": return ClickDropdownJson(uri); case "/runsetup/dropdown/select": return SelectDropdownJson(uri); case "/runsetup/results": return RunSetupResultsJson(); case "/runsetup/result/click": return ClickResultRowJson(uri); case "/runsetup/result-cell/click": return DispatchClickOnResultCellJson(uri); case "/runsetup/start-run": return StartRunJson(); case "/runsetup/preload-state": return PreloadStateJson(); case "/run/current-options": return CurrentRunOptionsJson(); case "/runsetup/open": return OpenSeedExplorerJson(); case "/runsetup/chosen-seed": return ChosenSeedJson(); case "/runsetup/dropdown/hover": return HoverDropdownOptionJson(uri); case "/runsetup/result-cell/hover": return HoverResultCellJson(uri); case "/runsetup/results/scroll": return ScrollResultsJson(uri, useRowOverride: false); case "/runsetup/results/scroll-over-row": return ScrollResultsJson(uri, useRowOverride: true); case "/runsetup/results/highlighted-row": return HighlightedRowJson(); case "/dialog/dismiss-corrupt-popup": return DismissCorruptPopupJson(); default: if (BattleAutomationEndpoints.IsBattleRoute(uri.AbsolutePath)) { string text = BattleAutomationEndpoints.Handle(uri, artifactDirectory); if (text != null) { return text; } } return JsonError("Unknown endpoint: " + uri.AbsolutePath); } } private static bool IsBackgroundSafeRoute(string path) { return path.Equals("/health", StringComparison.OrdinalIgnoreCase) || path.Equals("/status", StringComparison.OrdinalIgnoreCase); } private static bool RouteRequiresPreload(string path) { return path.Equals("/runsetup/dropdown/hover", StringComparison.OrdinalIgnoreCase) || path.Equals("/runsetup/result-cell/hover", StringComparison.OrdinalIgnoreCase); } private static bool RouteRequiresDialog(string path) { return path.StartsWith("/runsetup/dropdown/", StringComparison.OrdinalIgnoreCase) || path.StartsWith("/runsetup/result-cell/", StringComparison.OrdinalIgnoreCase) || path.Equals("/runsetup/results", StringComparison.OrdinalIgnoreCase) || path.Equals("/runsetup/result/click", StringComparison.OrdinalIgnoreCase) || path.Equals("/runsetup/results/highlighted-row", StringComparison.OrdinalIgnoreCase) || path.StartsWith("/runsetup/results/scroll", StringComparison.OrdinalIgnoreCase) || path.Equals("/runsetup/start-run", StringComparison.OrdinalIgnoreCase); } private static void WaitForPreloadOnListenerThread(TimeSpan timeout) { bool isPreloadStarted = SeedExplorerHoverPreview.IsPreloadStarted; bool isArtifactBackgroundPreloadStarted = SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadStarted; if ((isPreloadStarted || isArtifactBackgroundPreloadStarted) && !IsHoverPreloadComplete()) { DateTime dateTime = DateTime.UtcNow + timeout; while (DateTime.UtcNow < dateTime && !IsHoverPreloadComplete()) { Thread.Sleep(50); } } } private static bool IsHoverPreloadComplete() { return (!SeedExplorerHoverPreview.IsPreloadStarted || SeedExplorerHoverPreview.IsPreloadCompleted) && (!SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadStarted || SeedExplorerCardPreviewPrefabs.IsArtifactBackgroundPreloadCompleted); } private void WaitForSeedExplorerDialogOnListenerThread(TimeSpan timeout) { DateTime dateTime = DateTime.UtcNow + timeout; long seedExplorerDialogRegistrationCount = ModRegistry.SeedExplorerDialogRegistrationCount; bool ready; while (DateTime.UtcNow < dateTime && !(TryProbeDialogReady(out ready) && ready)) { Thread.Sleep(50); if (ModRegistry.SeedExplorerDialogRegistrationCount > seedExplorerDialogRegistrationCount) { break; } } } private bool TryProbeDialogReady(out bool ready) { ready = false; try { string text = InvokeOnMainThread(delegate { RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); return ((Object)(object)seedExplorerDialog != (Object)null) ? "1" : "0"; }); ready = text == "1"; return true; } catch { return false; } } private string HealthJson() { BumpListenerHeartbeat(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("plugin", "MTSeedExplorer") + "," + JsonProperty("version", "1.0.2") + "," + JsonProperty("frame", GetReportedFrame()) + "," + JsonProperty("unityFrame", lastObservedFrame) + "}"; } private string StatusJson() { BumpListenerHeartbeat(); return "{" + JsonProperty("plugin", "MTSeedExplorer") + "," + JsonProperty("version", "1.0.2") + "," + JsonProperty("frame", GetReportedFrame()) + "," + JsonProperty("unityFrame", lastObservedFrame) + "," + JsonProperty("artifactDirectory", artifactDirectory) + "," + JsonProperty("unityExplorerLoaded", IsUnityExplorerLoaded()) + "}"; } private static string ObjectsJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); string value; string contains = (dictionary.TryGetValue("contains", out value) ? value : ""); int result = 50; if (dictionary.TryGetValue("limit", out var value2)) { int.TryParse(value2, NumberStyles.None, CultureInfo.InvariantCulture, out result); } List list = new List(); GameObject[] array = Resources.FindObjectsOfTypeAll(); foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null) && Contains(((Object)val).name, contains)) { list.Add("{" + JsonProperty("type", "GameObject") + "," + JsonProperty("name", ((Object)val).name) + "," + JsonProperty("path", GetPath(val.transform)) + "," + JsonProperty("activeInHierarchy", val.activeInHierarchy) + "}"); if (list.Count >= result) { break; } } } if (list.Count < result) { TextMeshProUGUI[] array2 = Resources.FindObjectsOfTypeAll(); foreach (TextMeshProUGUI val2 in array2) { if (!((Object)(object)val2 == (Object)null) && ((TMP_Text)val2).text != null && Contains(((TMP_Text)val2).text, contains)) { list.Add("{" + JsonProperty("type", "TextMeshProUGUI") + "," + JsonProperty("name", ((Object)val2).name) + "," + JsonProperty("text", ((TMP_Text)val2).text) + "," + JsonProperty("path", GetPath(((TMP_Text)val2).transform)) + "," + JsonProperty("activeInHierarchy", ((Component)val2).gameObject.activeInHierarchy) + "}"); if (list.Count >= result) { break; } } } } return "{" + JsonProperty("count", list.Count) + ",\"objects\":[" + string.Join(",", list) + "]}"; } private string ScreenshotJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); string name = (dictionary.TryGetValue("name", out var value) ? value : "automation-screenshot.png"); name = SanitizeFileName(name); if (!name.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { name += ".png"; } Directory.CreateDirectory(artifactDirectory); string fullPath = Path.GetFullPath(Path.Combine(artifactDirectory, name)); ScreenCapture.CaptureScreenshot(fullPath); return "{" + JsonProperty("path", fullPath) + "," + JsonProperty("width", Screen.width) + "," + JsonProperty("height", Screen.height) + "}"; } private static string OpenSeedExplorerJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); if ((Object)(object)runSetupScreen == (Object)null) { return "{" + JsonProperty("opened", value: false) + "," + JsonProperty("reason", "RunSetupScreen was not found.") + "}"; } SeedExplorerDialog seedExplorerDialog = ModRegistry.GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return "{" + JsonProperty("opened", value: false) + "," + JsonProperty("reason", "SeedExplorerDialog was not registered.") + "}"; } seedExplorerDialog.Open("automation"); return "{" + JsonProperty("opened", value: true) + "}"; } private static string ChosenSeedJson() { int? num = (SeedExplorer.Instance?.SelectedSeedResult)?.Seed; string value = (((Object)(object)SeedExplorerFooterButton.ChosenSeedLabel != (Object)null) ? ((TMP_Text)SeedExplorerFooterButton.ChosenSeedLabel).text : ""); string value2 = ""; RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog != (Object)null) { value2 = seedExplorerDialog.GetDialogChosenSeedLabelText(); } return "{" + JsonProperty("ok", value: true) + "," + (num.HasValue ? JsonProperty("seed", num.Value) : "\"seed\":null") + "," + JsonProperty("seedHex", num.HasValue ? num.Value.ToString("X8") : "") + "," + JsonProperty("footerLabelText", value) + "," + JsonProperty("dialogLabelText", value2) + "}"; } private static string HoverDropdownOptionJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("id", out var value) || string.IsNullOrWhiteSpace(value)) { return JsonError("Missing required dropdown id query parameter."); } value = value.Trim().ToLowerInvariant(); if (!SeedExplorerUiAutomationIds.IsDropdownId(value)) { return JsonError("Unknown Seed Explorer dropdown id: " + value); } if (!dictionary.TryGetValue("optionIndex", out var value2) || !int.TryParse(value2, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return JsonError("optionIndex query parameter must be an integer."); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerHoverPreview.State state = seedExplorerDialog.HoverDropdownOptionForAutomation(value, result); return HoverPreviewStateJson(state); } private static string HoverResultCellJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("row", out var value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return JsonError("row query parameter must be an integer."); } if (!dictionary.TryGetValue("column", out var value2) || string.IsNullOrWhiteSpace(value2)) { return JsonError("Missing required column query parameter."); } string text = SeedExplorerUiAutomationIds.NormalizeResultColumnId(value2); if (!SeedExplorerUiAutomationIds.IsResultColumnId(text)) { return JsonError("Unknown result column id: '" + value2 + "'. Expected one of: " + string.Join(", ", SeedExplorerUiAutomationIds.ResultColumnIds)); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerHoverPreview.State state = seedExplorerDialog.HoverResultCellForAutomation(result, text); return HoverPreviewStateJson(state); } private static string DispatchClickOnResultCellJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("row", out var value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return JsonError("row query parameter must be an integer."); } if (!dictionary.TryGetValue("column", out var value2) || string.IsNullOrWhiteSpace(value2)) { return JsonError("Missing required column query parameter."); } string text = SeedExplorerUiAutomationIds.NormalizeResultColumnId(value2); if (!SeedExplorerUiAutomationIds.IsResultColumnId(text)) { return JsonError("Unknown result column id: '" + value2 + "'. Expected one of: " + string.Join(", ", SeedExplorerUiAutomationIds.ResultColumnIds)); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerDialog.ResultCellClickAutomationState resultCellClickAutomationState = seedExplorerDialog.DispatchClickOnResultCellForAutomation(result, text); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("row", resultCellClickAutomationState.RowIndex) + "," + JsonProperty("column", resultCellClickAutomationState.Column) + "," + JsonProperty("targetObjectName", resultCellClickAutomationState.TargetObjectName) + "," + JsonProperty("handlerObjectName", resultCellClickAutomationState.HandlerObjectName) + "," + JsonProperty("dialogOpen", resultCellClickAutomationState.DialogOpen) + "," + (resultCellClickAutomationState.ChosenSeed.HasValue ? JsonProperty("chosenSeed", resultCellClickAutomationState.ChosenSeed.Value) : "\"chosenSeed\":null") + "}"; } private static string HoverPreviewStateJson(SeedExplorerHoverPreview.State state) { return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("visible", state.Visible) + "," + JsonProperty("kind", state.Kind.ToString()) + "," + JsonProperty("title", state.Title) + "," + JsonProperty("body", state.Body) + "," + JsonProperty("visualReady", state.VisualReady) + "," + JsonProperty("visualKind", state.VisualKind ?? "") + "," + JsonProperty("visualSource", state.VisualSource ?? "") + "," + JsonProperty("resolvedTitle", state.ResolvedTitle ?? "") + "," + JsonProperty("resolvedBody", state.ResolvedBody ?? "") + "," + JsonProperty("renderedTitle", state.RenderedTitle ?? "") + "," + JsonProperty("renderedDescription", state.RenderedDescription ?? "") + "," + JsonProperty("upgradeBaseCardName", state.UpgradeBaseCardName ?? "") + "," + JsonProperty("hasArt", state.HasArt) + "," + JsonProperty("hasDescription", state.HasDescription) + "," + JsonProperty("leftAnchored", state.LeftAnchored) + "," + JsonProperty("backgroundReady", state.BackgroundReady) + "," + JsonProperty("backgroundSource", state.BackgroundSource ?? "") + "," + JsonProperty("backgroundGraphicCount", state.BackgroundGraphicCount) + ",\"backgroundLeft\":" + state.BackgroundLeft.ToString("R", CultureInfo.InvariantCulture) + ",\"backgroundTop\":" + state.BackgroundTop.ToString("R", CultureInfo.InvariantCulture) + ",\"backgroundRight\":" + state.BackgroundRight.ToString("R", CultureInfo.InvariantCulture) + ",\"backgroundBottom\":" + state.BackgroundBottom.ToString("R", CultureInfo.InvariantCulture) + ",\"panelLeft\":" + state.PanelLeft.ToString("R", CultureInfo.InvariantCulture) + ",\"panelTop\":" + state.PanelTop.ToString("R", CultureInfo.InvariantCulture) + ",\"panelWidth\":" + state.PanelWidth.ToString("R", CultureInfo.InvariantCulture) + ",\"panelHeight\":" + state.PanelHeight.ToString("R", CultureInfo.InvariantCulture) + "," + JsonProperty("visualChildCount", state.VisualChildCount) + ",\"visualWidth\":" + state.VisualWidth.ToString("R", CultureInfo.InvariantCulture) + ",\"visualHeight\":" + state.VisualHeight.ToString("R", CultureInfo.InvariantCulture) + ",\"screenWidth\":" + state.ScreenWidth.ToString("R", CultureInfo.InvariantCulture) + ",\"screenHeight\":" + state.ScreenHeight.ToString("R", CultureInfo.InvariantCulture) + ",\"contentLeft\":" + state.ContentLeft.ToString("R", CultureInfo.InvariantCulture) + ",\"contentTop\":" + state.ContentTop.ToString("R", CultureInfo.InvariantCulture) + ",\"contentRight\":" + state.ContentRight.ToString("R", CultureInfo.InvariantCulture) + ",\"contentBottom\":" + state.ContentBottom.ToString("R", CultureInfo.InvariantCulture) + "," + JsonProperty("corruptAssetDispatchCount", state.CorruptAssetDispatchCount) + "," + JsonProperty("corruptAssetDismissCount", AppDialogNotificationsPatches.DismissCount) + ",\"foregroundLeft\":" + state.ForegroundLeft.ToString("R", CultureInfo.InvariantCulture) + ",\"foregroundTop\":" + state.ForegroundTop.ToString("R", CultureInfo.InvariantCulture) + ",\"foregroundRight\":" + state.ForegroundRight.ToString("R", CultureInfo.InvariantCulture) + ",\"foregroundBottom\":" + state.ForegroundBottom.ToString("R", CultureInfo.InvariantCulture) + "}"; } private static string ScrollResultsJson(Uri uri, bool useRowOverride) { Dictionary dictionary = ParseQuery(uri.Query); float result = -1f; if (dictionary.TryGetValue("delta", out var value) && !float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { return JsonError("delta query parameter must be a number."); } int result2 = -1; if (useRowOverride && (!dictionary.TryGetValue("index", out var value2) || !int.TryParse(value2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2))) { return JsonError("index query parameter must be an integer for scroll-over-row."); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerDialog.ScrollAutomationState state = seedExplorerDialog.DispatchScrollForAutomation(result2, result); return ScrollStateJson(state); } private static string ScrollStateJson(SeedExplorerDialog.ScrollAutomationState state) { return "{" + JsonProperty("ok", value: true) + ",\"verticalNormalizedPosition\":" + state.VerticalNormalizedPosition.ToString("R", CultureInfo.InvariantCulture) + ",\"contentHeight\":" + state.ContentHeight.ToString("R", CultureInfo.InvariantCulture) + ",\"viewportHeight\":" + state.ViewportHeight.ToString("R", CultureInfo.InvariantCulture) + ",\"scrollableHeight\":" + state.ScrollableHeight.ToString("R", CultureInfo.InvariantCulture) + "," + JsonProperty("rowCount", state.RowCount) + "}"; } private static string HighlightedRowJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } int highlightedRowIndexForAutomation = seedExplorerDialog.GetHighlightedRowIndexForAutomation(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("highlightedRowIndex", highlightedRowIndexForAutomation) + "}"; } private static string DismissCorruptPopupJson() { int value = DialogShowPatches.DismissActiveCorruptionDialogs(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("dismissed", value) + "," + JsonProperty("totalDismissCount", AppDialogNotificationsPatches.DismissCount) + "}"; } private static string RunSetupSeedExplorerStateJson() { return RunSetupSeedExplorerStateJson(clickedChooseSeedButton: false); } private static string ShowRunSetupJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); if ((Object)(object)runSetupScreen != (Object)null && ((Component)runSetupScreen).gameObject.activeInHierarchy) { return RunSetupSeedExplorerStateJson(clickedChooseSeedButton: false, requestedRunSetupScreen: true); } if ((Object)(object)AllGameManagers.Instance == (Object)null) { return JsonError("AllGameManagers was not available."); } ScreenManager screenManager = AllGameManagers.Instance.GetScreenManager(); if ((Object)(object)screenManager == (Object)null) { return JsonError("ScreenManager was not available."); } screenManager.ShowScreen((ScreenName)42, (ScreenActiveCallback)null); return RunSetupSeedExplorerStateJson(clickedChooseSeedButton: false, requestedRunSetupScreen: true); } private static string ClickChooseSeedJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); if ((Object)(object)runSetupScreen == (Object)null) { return JsonError("RunSetupScreen was not found."); } GameUISelectableButton chooseSeedButton = GetChooseSeedButton(runSetupScreen); if ((Object)(object)chooseSeedButton == (Object)null) { return JsonError("Choose Seed button was not registered."); } ((UnityEvent)((Button)chooseSeedButton).onClick).Invoke(); return RunSetupSeedExplorerStateJson(clickedChooseSeedButton: true); } private static string ClickDropdownJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("id", out var value) || string.IsNullOrWhiteSpace(value)) { return JsonError("Missing required dropdown id query parameter."); } value = value.Trim().ToLowerInvariant(); if (!SeedExplorerUiAutomationIds.IsDropdownId(value)) { return JsonError("Unknown Seed Explorer dropdown id: " + value); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerDialog.DropdownAutomationState state = seedExplorerDialog.ClickDropdownForAutomation(value); return "{" + JsonProperty("ok", value: true) + "," + JsonRawProperty("dropdown", DropdownStateJson(state)) + "}"; } private static string SelectDropdownJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("id", out var value) || string.IsNullOrWhiteSpace(value)) { return JsonError("Missing required dropdown id query parameter."); } value = value.Trim().ToLowerInvariant(); if (!SeedExplorerUiAutomationIds.IsDropdownId(value)) { return JsonError("Unknown Seed Explorer dropdown id: " + value); } int? requestedIndex = null; if (dictionary.TryGetValue("index", out var value2) && !string.IsNullOrWhiteSpace(value2)) { if (!int.TryParse(value2, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return JsonError("Dropdown index must be an integer."); } requestedIndex = result; } dictionary.TryGetValue("value", out var value3); if (!requestedIndex.HasValue && string.IsNullOrWhiteSpace(value3)) { return JsonError("Dropdown selection requires either index or value."); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerDialog.DropdownAutomationState state = seedExplorerDialog.SelectDropdownOptionForAutomation(value, requestedIndex, value3); List resultRowsForAutomation = seedExplorerDialog.GetResultRowsForAutomation(); return "{" + JsonProperty("ok", value: true) + "," + JsonRawProperty("dropdown", DropdownStateJson(state)) + "," + JsonProperty("resultCount", resultRowsForAutomation.Count) + "," + JsonRawProperty("results", ResultRowsJson(resultRowsForAutomation)) + "}"; } private static string RunSetupResultsJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } List resultRowsForAutomation = seedExplorerDialog.GetResultRowsForAutomation(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("resultCount", resultRowsForAutomation.Count) + "," + JsonRawProperty("results", ResultRowsJson(resultRowsForAutomation)) + "}"; } private static string ClickResultRowJson(Uri uri) { Dictionary dictionary = ParseQuery(uri.Query); if (!dictionary.TryGetValue("index", out var value) || string.IsNullOrWhiteSpace(value)) { return JsonError("Missing required result row index query parameter."); } if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return JsonError("Result row index must be an integer."); } RunSetupScreen runSetupScreen = GetRunSetupScreen(); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); if ((Object)(object)seedExplorerDialog == (Object)null) { return JsonError("SeedExplorerDialog was not registered."); } SeedExplorerDialog.ResultRowAutomationState row = seedExplorerDialog.ClickResultRowForAutomation(result); return "{" + JsonProperty("ok", value: true) + "," + JsonRawProperty("row", ResultRowJson(row)) + "}"; } private static string StartRunJson() { RunSetupScreen runSetupScreen = GetRunSetupScreen(); if ((Object)(object)runSetupScreen == (Object)null) { return JsonError("RunSetupScreen was not found."); } Traverse.Create((object)runSetupScreen).Method("StartRun", Array.Empty()).GetValue(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("started", value: true) + "}"; } private static string CurrentRunOptionsJson() { SeedExplorer.ActiveRunOptionsSnapshot activeRunOptionsSnapshot = SeedExplorer.Instance.GetActiveRunOptionsSnapshot(); return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("ready", activeRunOptionsSnapshot.Ready) + "," + JsonProperty("reason", activeRunOptionsSnapshot.Reason) + "," + JsonRawProperty("selectedRow", SeedResultJson(activeRunOptionsSnapshot.SelectedRow)) + "," + JsonRawProperty("options", SeedResultJson(activeRunOptionsSnapshot.Options)) + "," + JsonRawProperty("cards", JsonStringArray(activeRunOptionsSnapshot.Cards)) + "," + JsonRawProperty("artifacts", JsonStringArray(activeRunOptionsSnapshot.Artifacts)) + "," + JsonRawProperty("upgrades", JsonStringArray(activeRunOptionsSnapshot.Upgrades)) + "}"; } private static string PreloadStateJson() { SeedExplorer instance = SeedExplorer.Instance; string value = instance.ContextSignature ?? ""; string value2 = instance.Status.ToString(); int targetSeedCount = instance.TargetSeedCount; int value3 = ((instance.SeedResults != null) ? instance.SeedResults.Count : 0); int value4 = ((instance.SeedResultsFiltered != null) ? instance.SeedResultsFiltered.Count : 0); string value5 = instance.LastError ?? ""; return "{" + JsonProperty("ok", value: true) + "," + JsonProperty("signature", value) + "," + JsonProperty("status", value2) + "," + JsonProperty("target", targetSeedCount) + "," + JsonProperty("completed", value3) + "," + JsonProperty("filtered", value4) + "," + JsonProperty("isSearching", instance.IsSearching) + "," + JsonProperty("version", instance.PreloadVersion.ToString(CultureInfo.InvariantCulture)) + "," + JsonProperty("lastError", value5) + "}"; } private static string RunSetupSeedExplorerStateJson(bool clickedChooseSeedButton) { return RunSetupSeedExplorerStateJson(clickedChooseSeedButton, requestedRunSetupScreen: false); } private static string RunSetupSeedExplorerStateJson(bool clickedChooseSeedButton, bool requestedRunSetupScreen) { RunSetupScreen runSetupScreen = GetRunSetupScreen(); GameUISelectableButton chooseSeedButton = GetChooseSeedButton(runSetupScreen); SeedExplorerDialog seedExplorerDialog = GetSeedExplorerDialog(runSetupScreen); List values = new List { JsonProperty("ok", value: true), JsonProperty("runSetupPresent", (Object)(object)runSetupScreen != (Object)null), JsonProperty("chooseSeedButtonPresent", (Object)(object)chooseSeedButton != (Object)null && ((Component)chooseSeedButton).gameObject.activeInHierarchy), JsonProperty("chooseSeedButtonObjectName", ((Object)(object)chooseSeedButton != (Object)null) ? ((Object)((Component)chooseSeedButton).gameObject).name : ""), JsonProperty("clickedChooseSeedButton", clickedChooseSeedButton), JsonProperty("requestedRunSetupScreen", requestedRunSetupScreen), JsonProperty("dialogRegistered", (Object)(object)seedExplorerDialog != (Object)null), JsonProperty("dialogOpen", (Object)(object)seedExplorerDialog != (Object)null && seedExplorerDialog.IsOpenForAutomation()), JsonRawProperty("dropdowns", DropdownStatesJson(seedExplorerDialog)) }; return "{" + string.Join(",", values) + "}"; } private static string DropdownStatesJson(SeedExplorerDialog dialog) { IEnumerable enumerable; if (!((Object)(object)dialog != (Object)null)) { enumerable = SeedExplorerUiAutomationIds.DropdownIds.Select((string id) => new SeedExplorerDialog.DropdownAutomationState(id, present: false, expanded: false, 0, -1, "", new List())); } else { IEnumerable dropdownAutomationStates = dialog.GetDropdownAutomationStates(); enumerable = dropdownAutomationStates; } IEnumerable source = enumerable; return "[" + string.Join(",", source.Select(DropdownStateJson)) + "]"; } private static string DropdownStateJson(SeedExplorerDialog.DropdownAutomationState state) { return "{" + JsonProperty("id", state.Id) + "," + JsonProperty("present", state.Present) + "," + JsonProperty("expanded", state.Expanded) + "," + JsonProperty("optionCount", state.OptionCount) + "," + JsonProperty("selectedIndex", state.SelectedIndex) + "," + JsonProperty("selectedValue", state.SelectedValue) + "," + JsonRawProperty("options", JsonStringArray(state.Options)) + "}"; } private static RunSetupScreen GetRunSetupScreen() { try { if ((Object)(object)AllGameManagers.Instance == (Object)null) { return FindRunSetupScreen(); } ScreenManager screenManager = AllGameManagers.Instance.GetScreenManager(); RunSetupScreen val = (RunSetupScreen)(((Object)(object)screenManager != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); return val ?? FindRunSetupScreen(); } catch { return FindRunSetupScreen(); } } private static RunSetupScreen FindRunSetupScreen() { RunSetupScreen val = null; RunSetupScreen[] array = Resources.FindObjectsOfTypeAll(); foreach (RunSetupScreen val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if (((Component)val2).gameObject.activeInHierarchy) { return val2; } val = val ?? val2; } } return val; } private static GameUISelectableButton GetChooseSeedButton(RunSetupScreen runSetupScreen) { GameUISelectableButton val = (((Object)(object)runSetupScreen != (Object)null) ? ModRegistry.GetSeedExplorerFooterButton(runSetupScreen) : null); if ((Object)(object)val != (Object)null) { return val; } return ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((GameUISelectableButton candidate) => (Object)(object)candidate != (Object)null && ((Object)candidate).name == SeedExplorerUiAutomationIds.ChooseSeedButtonObjectName)); } private static SeedExplorerDialog GetSeedExplorerDialog(RunSetupScreen runSetupScreen) { SeedExplorerDialog seedExplorerDialog = (((Object)(object)runSetupScreen != (Object)null) ? ModRegistry.GetSeedExplorerDialog(runSetupScreen) : null); if ((Object)(object)seedExplorerDialog != (Object)null) { return seedExplorerDialog; } seedExplorerDialog = Resources.FindObjectsOfTypeAll().FirstOrDefault((SeedExplorerDialog candidate) => (Object)(object)candidate != (Object)null && (Object)(object)((Component)candidate).gameObject != (Object)null); if ((Object)(object)seedExplorerDialog != (Object)null) { if ((Object)(object)runSetupScreen != (Object)null) { try { ModRegistry.RegisterSeedExplorerDialog(runSetupScreen, seedExplorerDialog); } catch { } } return seedExplorerDialog; } RunSetupScreen val = runSetupScreen ?? GetRunSetupScreen(); Plugin.Log("SeedExplorerDialog lookup miss: runSetupScreen=" + (((Object)(object)runSetupScreen != (Object)null) ? "set" : "null") + " target=" + (((Object)(object)val != (Object)null) ? "set" : "null")); if ((Object)(object)val != (Object)null) { try { Plugin.Log("SeedExplorerDialog missing post-show; re-instantiating on demand."); SeedExplorerDialog seedExplorerDialog2 = SeedExplorerDialog.Instantiate(val); ModRegistry.RegisterSeedExplorerDialog(val, seedExplorerDialog2); return seedExplorerDialog2; } catch (Exception ex) { Plugin.LogError("On-demand SeedExplorerDialog re-instantiation failed: " + ex); } } return null; } private static bool IsUnityExplorerLoaded() { return AppDomain.CurrentDomain.GetAssemblies().Any((Assembly assembly) => assembly.GetName().Name.IndexOf("UnityExplorer", StringComparison.OrdinalIgnoreCase) >= 0); } private static bool Contains(string value, string contains) { return string.IsNullOrEmpty(contains) || value.IndexOf(contains, StringComparison.OrdinalIgnoreCase) >= 0; } private static string GetPath(Transform transform) { Stack stack = new Stack(); Transform val = transform; while ((Object)(object)val != (Object)null) { stack.Push(((Object)val).name); val = val.parent; } return string.Join("/", stack.ToArray()); } private static Dictionary ParseQuery(string query) { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrEmpty(query)) { return dictionary; } string[] array = query.TrimStart('?').Split('&'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(new char[1] { '=' }, 2); string key = Uri.UnescapeDataString(array2[0]); string value = ((array2.Length == 2) ? Uri.UnescapeDataString(array2[1]) : ""); dictionary[key] = value; } } return dictionary; } private static string SanitizeFileName(string name) { string text = Path.GetFileName(name); char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); foreach (char oldChar in invalidFileNameChars) { text = text.Replace(oldChar, '_'); } return string.IsNullOrWhiteSpace(text) ? "automation-screenshot.png" : text; } private static void WriteResponse(Stream stream, int statusCode, string json) { byte[] bytes = Encoding.UTF8.GetBytes(json); string text = ((statusCode == 200) ? "OK" : "Error"); string s = "HTTP/1.1 " + statusCode + " " + text + "\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: " + bytes.Length + "\r\nConnection: close\r\n\r\n"; byte[] bytes2 = Encoding.ASCII.GetBytes(s); stream.Write(bytes2, 0, bytes2.Length); stream.Write(bytes, 0, bytes.Length); } private static string JsonError(string message) { return "{" + JsonProperty("ok", value: false) + "," + JsonProperty("error", message) + "}"; } private static string JsonRawProperty(string name, string json) { return "\"" + JsonEscape(name) + "\":" + json; } private static string JsonStringArray(IEnumerable values) { if (values == null) { return "[]"; } return "[" + string.Join(",", values.Select((string value) => "\"" + JsonEscape(value ?? "") + "\"")) + "]"; } private static string ResultRowsJson(IEnumerable rows) { return "[" + string.Join(",", rows.Select(ResultRowJson)) + "]"; } private static string ResultRowJson(SeedExplorerDialog.ResultRowAutomationState row) { return "{" + JsonProperty("index", row.Index) + "," + SeedResultJsonProperties(row.Result) + "}"; } private static string SeedResultJson(SeedExplorer.SeedResult result) { if (result == null) { return "null"; } return "{" + SeedResultJsonProperties(result) + "}"; } private static string SeedResultJsonProperties(SeedExplorer.SeedResult result) { int value = result?.Seed ?? 0; string value2 = ((result != null) ? result.Card1 : ""); string value3 = ((result != null) ? result.Card2 : ""); string value4 = ((result != null) ? result.Card3 : ""); string text = ((result != null) ? result.Artifact1 : ""); string text2 = ((result != null) ? result.Artifact2 : ""); string text3 = ((result != null) ? result.Upgrade1 : ""); string text4 = ((result != null) ? result.Upgrade2 : ""); return JsonProperty("seed", value) + "," + JsonProperty("primaryCard", value2) + "," + JsonProperty("secondaryCard", value3) + "," + JsonProperty("unitCard", value4) + "," + JsonProperty("artifact1", text) + "," + JsonProperty("artifact2", text2) + "," + JsonProperty("upgrade1", text3) + "," + JsonProperty("upgrade2", text4) + "," + JsonRawProperty("artifacts", JsonStringArray(new string[2] { text, text2 })) + "," + JsonRawProperty("upgrades", JsonStringArray(new string[2] { text3, text4 })); } private static string JsonProperty(string name, string value) { return "\"" + JsonEscape(name) + "\":\"" + JsonEscape(value ?? "") + "\""; } private static string JsonProperty(string name, bool value) { return "\"" + JsonEscape(name) + "\":" + (value ? "true" : "false"); } private static string JsonProperty(string name, int value) { return "\"" + JsonEscape(name) + "\":" + value.ToString(CultureInfo.InvariantCulture); } private static string JsonEscape(string value) { StringBuilder stringBuilder = new StringBuilder(value.Length + 8); foreach (char c in value) { switch (c) { case '\\': stringBuilder.Append("\\\\"); continue; case '"': stringBuilder.Append("\\\""); continue; case '\r': stringBuilder.Append("\\r"); continue; case '\n': stringBuilder.Append("\\n"); continue; case '\t': stringBuilder.Append("\\t"); continue; } if (char.IsControl(c)) { stringBuilder.Append("\\u"); int num = c; stringBuilder.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } public void Dispose() { if (!isDisposed) { isDisposed = true; if (activeBridge == this) { activeBridge = null; } listener.Stop(); if ((Object)(object)updaterObject != (Object)null) { Object.Destroy((Object)(object)updaterObject); updaterObject = null; } } } } internal static class BattleAutomationEndpoints { internal static string Handle(Uri uri, string artifactDirectory) { return uri.AbsolutePath.ToLowerInvariant() switch { "/battle/state" => BattleStateJson(), "/battle/list-scenarios" => ListScenariosJson(uri), "/battle/start-by-name" => StartBattleByNameJson(uri), "/battle/end-turn" => EndTurnJson(), "/battle/discard" => DiscardJson(uri), "/battle/undo" => UndoJson(), "/battle/wait-ready" => WaitReadyJson(), _ => null, }; } internal static bool IsBattleRoute(string path) { return path?.StartsWith("/battle/", StringComparison.OrdinalIgnoreCase) ?? false; } private static string BattleStateJson() { //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) try { AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); CombatManager val2 = (((Object)(object)instance != (Object)null) ? instance.GetCombatManager() : null); CardManager val3 = (((Object)(object)instance != (Object)null) ? instance.GetCardManager() : null); IExternalAccess val4 = (((Object)(object)val != (Object)null) ? val.GetReplayData() : null); ReplayData val5 = TryGetUnderlyingReplayData(val); bool flag = (Object)(object)val != (Object)null && val.IsInBattle(); bool flag2 = (Object)(object)val != (Object)null && val.IsInUndoMode; int num = (((Object)(object)val2 != (Object)null) ? val2.GetTurnCount() : (-1)); object obj; if (!((Object)(object)val2 != (Object)null)) { obj = "?"; } else { Phase combatPhase = val2.GetCombatPhase(); obj = ((object)(Phase)(ref combatPhase)).ToString(); } string value = (string)obj; int num2 = ((val5 == null) ? (-1) : (Traverse.Create((object)val5).Field>("replayEntries").Value?.Count ?? (-1))); int num3 = ((val5 != null) ? Traverse.Create((object)val5).Field("lastEndTurnEntryIndex").Value : (-2)); int num4 = ((val5 != null) ? Traverse.Create((object)val5).Field("battleBeginEntryIndex").Value : (-2)); List list = (((Object)(object)val3 != (Object)null) ? val3.GetHand(false) : new List()); StringBuilder stringBuilder = new StringBuilder("["); for (int i = 0; i < list.Count; i++) { if (i > 0) { stringBuilder.Append(","); } string text = ((list[i] != null) ? list[i].GetAssetName() : ""); stringBuilder.Append("\"").Append(JsonEscape(text ?? "")).Append("\""); } stringBuilder.Append("]"); string text2 = stringBuilder.ToString(); return "{\"ok\":true,\"inBattle\":" + (flag ? "true" : "false") + ",\"inUndoMode\":" + (flag2 ? "true" : "false") + ",\"turnCount\":" + num.ToString(CultureInfo.InvariantCulture) + ",\"phase\":\"" + JsonEscape(value) + "\",\"handCount\":" + list.Count.ToString(CultureInfo.InvariantCulture) + ",\"hand\":" + text2 + ",\"replayCount\":" + num2.ToString(CultureInfo.InvariantCulture) + ",\"lastEndTurnEntryIndex\":" + num3.ToString(CultureInfo.InvariantCulture) + ",\"battleBeginEntryIndex\":" + num4.ToString(CultureInfo.InvariantCulture) + "}"; } catch (Exception ex) { return JsonError("BattleState failed: " + ex); } } private static string StartBattleByNameJson(Uri uri) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown try { Dictionary dictionary = ParseQuery(uri.Query); string value; string text = (dictionary.TryGetValue("name", out value) ? value : ""); AllGameManagers managers = AllGameManagers.Instance; SaveManager saveManager = (((Object)(object)managers != (Object)null) ? managers.GetSaveManager() : null); if ((Object)(object)saveManager == (Object)null) { return JsonError("SaveManager not available."); } ScenarioData scenario = FindScenario(saveManager, text); if ((Object)(object)scenario == (Object)null) { return JsonError("Scenario not found: " + text); } bool isEmpty = text == "CheatCommandEmptyLevel"; LoadingScreen.AddTask((LoadingTask)new LoadInstantly((DisplayStyle)5, (Action)delegate { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown saveManager.EnableTestScenario(scenario, isEmpty); LoadingScreen.AddTask((LoadingTask)new LoadTrainAssets((DisplayStyle)2, (Action)null), true); LoadingScreen.AddTask((LoadingTask)new LoadClassAssets((DisplayStyle)2, (Action)null), true); LoadingScreen.AddTask((LoadingTask)new LoadScenarioAssets(saveManager.GetCurrentScenarioData(), saveManager.GetCurrentScenarioBossCharacter(), (DisplayStyle)2, (Action)delegate { saveManager.SetGameSequence((GameSequence)1, true); ScreenManager screenManager = managers.GetScreenManager(); if ((Object)(object)screenManager != (Object)null) { screenManager.ShowScreen((ScreenName)1, (ScreenActiveCallback)null); } }), true); }, false), true); return "{\"ok\":true,\"started\":true,\"scenario\":\"" + JsonEscape(((Object)scenario).name) + "\"}"; } catch (Exception ex) { return JsonError("StartBattleByName failed: " + ex); } } private static string EndTurnJson() { try { AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); CombatManager val2 = (((Object)(object)instance != (Object)null) ? instance.GetCombatManager() : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return JsonError("Managers unavailable."); } if (!val.IsInBattle()) { return JsonError("Not in battle."); } ((MonoBehaviour)val).StartCoroutine(val.Cheat_EndTurn((Action)null)); return "{\"ok\":true,\"endTurnRequested\":true}"; } catch (Exception ex) { return JsonError("EndTurn failed: " + ex); } } private static string DiscardJson(Uri uri) { try { Dictionary dictionary = ParseQuery(uri.Query); int result = 0; if (dictionary.TryGetValue("index", out var value)) { int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result); } AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); if ((Object)(object)val == (Object)null) { return JsonError("SaveManager unavailable."); } if (!val.IsInBattle()) { return JsonError("Not in battle."); } ((MonoBehaviour)val).StartCoroutine(val.Cheat_Discard(result)); return "{\"ok\":true,\"discardRequested\":true,\"index\":" + result.ToString(CultureInfo.InvariantCulture) + "}"; } catch (Exception ex) { return JsonError("Discard failed: " + ex); } } private static string UndoJson() { try { AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); if ((Object)(object)val == (Object)null) { return JsonError("SaveManager unavailable."); } if (!val.IsInBattle()) { return JsonError("Not in battle."); } val.UndoTurn(true); return "{\"ok\":true,\"undoRequested\":true}"; } catch (Exception ex) { return JsonError("Undo failed: " + ex); } } private static string WaitReadyJson() { return BattleStateJson(); } private static string ListScenariosJson(Uri uri) { try { Dictionary dictionary = ParseQuery(uri.Query); string value; string value2 = (dictionary.TryGetValue("filter", out value) ? value : ""); AllGameManagers instance = AllGameManagers.Instance; SaveManager val = (((Object)(object)instance != (Object)null) ? instance.GetSaveManager() : null); if ((Object)(object)val == (Object)null) { return JsonError("SaveManager unavailable."); } AllGameData allGameData = val.GetAllGameData(); if ((Object)(object)allGameData == (Object)null) { return JsonError("AllGameData unavailable."); } IReadOnlyList allScenarioDatas = allGameData.GetAllScenarioDatas(); StringBuilder stringBuilder = new StringBuilder("{\"ok\":true,\"scenarios\":["); bool flag = true; int num = 0; if (allScenarioDatas != null) { for (int i = 0; i < allScenarioDatas.Count; i++) { ScenarioData val2 = allScenarioDatas[i]; if ((Object)(object)val2 == (Object)null) { continue; } string text = ((Object)val2).name ?? ""; if (string.IsNullOrEmpty(value2) || text.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { if (!flag) { stringBuilder.Append(","); } flag = false; stringBuilder.Append("\"").Append(JsonEscape(text)).Append("\""); num++; } } } stringBuilder.Append("],\"count\":").Append(num.ToString(CultureInfo.InvariantCulture)).Append("}"); return stringBuilder.ToString(); } catch (Exception ex) { return JsonError("ListScenarios failed: " + ex); } } private static ReplayData TryGetUnderlyingReplayData(SaveManager saveManager) { if ((Object)(object)saveManager == (Object)null) { return null; } try { SaveData value = Traverse.Create((object)saveManager).Property("ActiveSaveData", (object[])null).GetValue(); if (value == null) { return null; } return Traverse.Create((object)value).Method("GetReplayData", Array.Empty()).GetValue(); } catch { return null; } } private static ScenarioData FindScenario(SaveManager saveManager, string name) { try { AllGameData val = (((Object)(object)saveManager != (Object)null) ? saveManager.GetAllGameData() : null); if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(name)) { return null; } IReadOnlyList allScenarioDatas = val.GetAllScenarioDatas(); if (allScenarioDatas == null) { return null; } for (int i = 0; i < allScenarioDatas.Count; i++) { ScenarioData val2 = allScenarioDatas[i]; if ((Object)(object)val2 != (Object)null && string.Equals(((Object)val2).name, name, StringComparison.OrdinalIgnoreCase)) { return val2; } } return null; } catch { return null; } } private static Dictionary ParseQuery(string query) { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrEmpty(query)) { return dictionary; } string[] array = query.TrimStart('?').Split('&'); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { string[] array2 = text.Split(new char[1] { '=' }, 2); dictionary[Uri.UnescapeDataString(array2[0])] = ((array2.Length == 2) ? Uri.UnescapeDataString(array2[1]) : ""); } } return dictionary; } private static string JsonError(string message) { return "{\"ok\":false,\"error\":\"" + JsonEscape(message ?? "") + "\"}"; } private static string JsonEscape(string value) { if (value == null) { return ""; } StringBuilder stringBuilder = new StringBuilder(value.Length + 8); foreach (char c in value) { switch (c) { case '\\': stringBuilder.Append("\\\\"); continue; case '"': stringBuilder.Append("\\\""); continue; case '\r': stringBuilder.Append("\\r"); continue; case '\n': stringBuilder.Append("\\n"); continue; case '\t': stringBuilder.Append("\\t"); continue; } if (char.IsControl(c)) { stringBuilder.Append("\\u"); int num = c; stringBuilder.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } } }