using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameState; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UI; using UI.PactHistory; using UI.SelectableWindow.Cell; using UI.SelectableWindow.ISelectableWindows; using UI.SelectableWindow.Managers; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LwfPactHistoryExporter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8f98a9416b942a8d71dd1e3e26dc6cb0967de454")] [assembly: AssemblyProduct("LwfPactHistoryExporter")] [assembly: AssemblyTitle("LwfPactHistoryExporter")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LwfPactHistoryExporter { internal static class PactHistoryExportService { private sealed class PactHistoryExportRunner : MonoBehaviour { internal void StartExport(bool isTestExport, int testPanelCount) { ((MonoBehaviour)this).StartCoroutine(ExportRoutine(isTestExport, testPanelCount)); } private IEnumerator ExportRoutine(bool isTestExport, int testPanelCount) { _isExporting = true; try { IReadOnlyList snapshots = PactHistoryStore.GetSnapshots(); if (snapshots == null || snapshots.Count == 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Pact history export skipped because there are no pact history entries."); } yield break; } if (isTestExport) { snapshots = CreateTestSnapshots(snapshots, testPanelCount); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"Starting development test export with {snapshots.Count} pact panels."); } } PactCellComponents template = FindCellTemplate(); if (!Object.op_Implicit((Object)(object)template)) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogError((object)"Pact history export failed because the game pact cell template was not found."); } yield break; } template.Initialize(); float cellWidth = ResolveCellWidth(template); float cellHeight = ResolveCellHeight(template); int maxTextureSize = SystemInfo.maxTextureSize; if (cellWidth > (float)maxTextureSize) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogError((object)$"Pact history export failed because the pact panel width ({cellWidth}) exceeds the texture limit ({maxTextureSize})."); } yield break; } bool includePactTimestamps = PactHistoryExportSettings.IncludePactTimestamps != null && PactHistoryExportSettings.IncludePactTimestamps.Value; bool exportAsJpeg = IsJpegOutput(); float num = cellHeight + (includePactTimestamps ? 32f : 0f); int columnCount = Mathf.Min(5, snapshots.Count); while (columnCount > 1 && GetPageWidth(cellWidth, columnCount) > (float)maxTextureSize) { columnCount--; } if (GetPageWidth(cellWidth, columnCount) > (float)maxTextureSize) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogError((object)$"Pact history export failed because the image width ({GetPageWidth(cellWidth, columnCount)}) exceeds the texture limit ({maxTextureSize})."); } yield break; } int num2 = Mathf.Max(1, Mathf.FloorToInt(((float)maxTextureSize - 48f + 16f) / (num + 16f))); int entriesPerPage = Mathf.Max(1, columnCount * num2); DateTime exportedAt = DateTime.Now; string exportDirectory = Path.Combine(Paths.GameRootPath, "PactHistoryExports"); Directory.CreateDirectory(exportDirectory); int pageCount = Mathf.CeilToInt((float)snapshots.Count / (float)entriesPerPage); List exportedPaths = new List(pageCount); for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) { int num3 = pageIndex * entriesPerPage; int entryCount = Mathf.Min(entriesPerPage, snapshots.Count - num3); string outputPath = GetOutputPath(exportDirectory, exportedAt, pageIndex, pageCount, exportAsJpeg, isTestExport); yield return CapturePage(template, snapshots, num3, entryCount, columnCount, cellWidth, cellHeight, includePactTimestamps, exportAsJpeg, outputPath); exportedPaths.Add(outputPath); } ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogInfo((object)$"Exported {snapshots.Count} pact history panels to {exportedPaths.Count} image file(s): {exportDirectory}"); } } finally { _isExporting = false; } } private IEnumerator CapturePage(PactCellComponents template, IReadOnlyList snapshots, int firstEntryIndex, int entryCount, int columnCount, float cellWidth, float cellHeight, bool includePactTimestamps, bool exportAsJpeg, string outputPath) { float num = cellHeight + (includePactTimestamps ? 32f : 0f); int num2 = Mathf.CeilToInt((float)entryCount / (float)columnCount); float num3 = 48f + (float)num2 * num + (float)(num2 - 1) * 16f; int textureWidth = Mathf.CeilToInt(GetPageWidth(cellWidth, columnCount)); int textureHeight = Mathf.CeilToInt(num3); RenderTexture renderTexture = null; Texture2D texture = null; GameObject cameraObject = null; GameObject canvasObject = null; RenderTexture previousRenderTexture = RenderTexture.active; try { renderTexture = new RenderTexture(textureWidth, textureHeight, 24, (RenderTextureFormat)0) { antiAliasing = 1 }; renderTexture.Create(); cameraObject = new GameObject("PactHistoryExportCamera"); Camera camera = cameraObject.AddComponent(); camera.clearFlags = (CameraClearFlags)2; camera.backgroundColor = Color.clear; camera.cullingMask = int.MinValue; camera.orthographic = true; camera.targetTexture = renderTexture; ((Behaviour)camera).enabled = false; canvasObject = new GameObject("PactHistoryExportCanvas", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); SetLayerRecursively(canvasObject, 31); Canvas component = canvasObject.GetComponent(); component.renderMode = (RenderMode)1; component.worldCamera = camera; component.planeDistance = 1f; component.pixelPerfect = true; canvasObject.GetComponent().uiScaleMode = (ScaleMode)0; TMP_FontAsset font = ResolveFont(template); for (int i = 0; i < entryCount; i++) { PactCellSnapshot val = snapshots[firstEntryIndex + i]; int num4 = i % columnCount; int num5 = i / columnCount; float num6 = 24f + (float)num4 * (cellWidth + 16f); float num7 = 24f + (float)num5 * (num + 16f); if (includePactTimestamps) { CreatePactTimestamp(((Component)component).transform, font, val, num6, num7, cellWidth); num7 += 32f; } PactCellComponents obj = Object.Instantiate(template, ((Component)component).transform); SetLayerRecursively(((Component)obj).gameObject, 31); obj.Initialize(); obj.ApplySnapshot(val); Transform transform = ((Component)obj).transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (Object.op_Implicit((Object)(object)val2)) { val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(cellWidth, cellHeight); val2.anchoredPosition = new Vector2(num6, 0f - num7); LayoutRebuilder.ForceRebuildLayoutImmediate(val2); } } yield return (object)new WaitForEndOfFrame(); Canvas.ForceUpdateCanvases(); camera.Render(); RenderTexture.active = renderTexture; texture = new Texture2D(textureWidth, textureHeight, (TextureFormat)4, false); texture.ReadPixels(new Rect(0f, 0f, (float)textureWidth, (float)textureHeight), 0, 0); texture.Apply(); File.WriteAllBytes(outputPath, exportAsJpeg ? EncodeJpeg(texture) : ImageConversion.EncodeToPNG(texture)); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Pact history image written: " + outputPath)); } } finally { RenderTexture.active = previousRenderTexture; if (Object.op_Implicit((Object)(object)texture)) { Object.Destroy((Object)(object)texture); } if (Object.op_Implicit((Object)(object)canvasObject)) { Object.Destroy((Object)(object)canvasObject); } if (Object.op_Implicit((Object)(object)cameraObject)) { Object.Destroy((Object)(object)cameraObject); } if ((Object)(object)renderTexture != (Object)null) { renderTexture.Release(); Object.Destroy((Object)(object)renderTexture); } } } } private const string ExportDirectoryName = "PactHistoryExports"; private const float DefaultCellWidth = 960f; private const float DefaultCellHeight = 520f; private const float TimestampHeight = 32f; private const float Padding = 24f; private const float CellSpacing = 16f; private const int PreferredColumnCount = 5; private const int CaptureLayer = 31; private static readonly Dictionary PactElapsedTimes = new Dictionary(); private static PactHistoryExportRunner _runner; private static bool _isExporting; internal static void RecordPactTimestamp(PactCellSnapshot snapshot) { if (snapshot != null) { GameStateManager instance = GameStateManager.Instance; if (Object.op_Implicit((Object)(object)instance)) { PactElapsedTimes[snapshot] = instance.GetElapsedGameplaySeconds(); } } } internal static void ClearPactTimestamps() { PactElapsedTimes.Clear(); } internal static void RequestExport() { RequestExport(isTestExport: false, 0); } internal static void RequestDebugExport() { int num = PactHistoryExportSettings.DebugTestPanelCount?.Value ?? 0; if (num > 0) { RequestExport(isTestExport: true, num); } } private static void RequestExport(bool isTestExport, int testPanelCount) { if (_isExporting) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Pact history export is already in progress."); } return; } PactHistoryExportRunner orCreateRunner = GetOrCreateRunner(); if ((Object)(object)orCreateRunner == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)"Could not create the pact history export runner."); } } else { orCreateRunner.StartExport(isTestExport, testPanelCount); } } private static PactHistoryExportRunner GetOrCreateRunner() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)_runner)) { return _runner; } GameObject val = new GameObject("LwfPactHistoryExporter"); Object.DontDestroyOnLoad((Object)val); _runner = val.AddComponent(); return _runner; } private static PactCellComponents FindCellTemplate() { PactHistoryUIController val = Object.FindFirstObjectByType((FindObjectsInactive)1); if (!Object.op_Implicit((Object)(object)val)) { return null; } object? obj = AccessTools.Field(typeof(PactHistoryUIController), "_cellTemplate")?.GetValue(val); return (PactCellComponents)((obj is PactCellComponents) ? obj : null); } private static float ResolveCellWidth(PactCellComponents template) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)template).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); float num; if (!Object.op_Implicit((Object)(object)val)) { num = 0f; } else { Rect rect = val.rect; num = ((Rect)(ref rect)).width; } float num2 = num; if (!(num2 > 1f)) { return 960f; } return num2; } private static float ResolveCellHeight(PactCellComponents template) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_004c: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)template).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!Object.op_Implicit((Object)(object)val)) { return 520f; } float preferredHeight = LayoutUtility.GetPreferredHeight(val); if (preferredHeight > 1f) { return preferredHeight; } Rect rect = val.rect; if (!(((Rect)(ref rect)).height > 1f)) { return 520f; } rect = val.rect; return ((Rect)(ref rect)).height; } private static TMP_FontAsset ResolveFont(PactCellComponents template) { TextMeshProUGUI componentInChildren = ((Component)template).GetComponentInChildren(true); if (!Object.op_Implicit((Object)(object)componentInChildren)) { return TMP_Settings.defaultFontAsset; } return ((TMP_Text)componentInChildren).font; } private static void CreatePactTimestamp(Transform parent, TMP_FontAsset font, PactCellSnapshot snapshot, float x, float y, float width) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) double value; string text = (PactElapsedTimes.TryGetValue(snapshot, out value) ? FormatElapsedTime(value) : "—"); CreateText(parent, "PactTimestamp", font, text, new Vector2(x, 0f - y), new Vector2(width, 32f), (TextAlignmentOptions)513); } private static string FormatElapsedTime(double elapsedSeconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(Math.Max(0.0, elapsedSeconds)); if (!(timeSpan.TotalHours >= 1.0)) { return timeSpan.ToString("mm\\:ss", CultureInfo.InvariantCulture); } return timeSpan.ToString("hh\\:mm\\:ss", CultureInfo.InvariantCulture); } private static float GetPageWidth(float cellWidth, int columnCount) { return 48f + (float)columnCount * cellWidth + (float)(columnCount - 1) * 16f; } private static void CreateText(Transform parent, string name, TMP_FontAsset font, string text, Vector2 position, Vector2 size, TextAlignmentOptions alignment) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) if (!((Object)(object)font == (Object)null)) { GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }) { layer = 31 }; val.transform.SetParent(parent, false); Transform transform = val.transform; Transform obj = ((transform is RectTransform) ? transform : null); ((RectTransform)obj).anchorMin = new Vector2(0f, 1f); ((RectTransform)obj).anchorMax = new Vector2(0f, 1f); ((RectTransform)obj).pivot = new Vector2(0f, 1f); ((RectTransform)obj).anchoredPosition = position; ((RectTransform)obj).sizeDelta = size; TextMeshProUGUI component = val.GetComponent(); ((TMP_Text)component).font = font; ((TMP_Text)component).fontSize = 28f; ((TMP_Text)component).alignment = alignment; ((Graphic)component).color = Color.white; ((TMP_Text)component).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)component).text = text; } } private static bool IsJpegOutput() { string a = PactHistoryExportSettings.OutputFormat?.Value; if (!string.Equals(a, "jpg", StringComparison.OrdinalIgnoreCase)) { return string.Equals(a, "jpeg", StringComparison.OrdinalIgnoreCase); } return true; } private static IReadOnlyList CreateTestSnapshots(IReadOnlyList snapshots, int requestedCount) { int num = Mathf.Max(1, requestedCount); List list = new List(num); for (int i = 0; i < num; i++) { list.Add(snapshots[i % snapshots.Count]); } return list; } private static byte[] EncodeJpeg(Texture2D texture) { int num = Mathf.Clamp(PactHistoryExportSettings.JpegQuality?.Value ?? 90, 1, 100); int num2 = Mathf.Max(0, PactHistoryExportSettings.JpegTargetSizeMiB?.Value ?? 8); long num3 = (long)num2 * 1024L * 1024; byte[] array = ImageConversion.EncodeToJPG(texture, num); while (num3 > 0 && array.Length > num3 && num > 50) { num = Mathf.Max(50, num - 5); array = ImageConversion.EncodeToJPG(texture, num); } if (num3 > 0 && array.Length > num3) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"JPEG export is {(float)array.Length / 1048576f:F1} MiB, above the configured {num2} MiB target at JPEG quality {num}."); } } return array; } private static string GetOutputPath(string exportDirectory, DateTime exportedAt, int pageIndex, int pageCount, bool exportAsJpeg, bool isTestExport) { string text = string.Format("PactHistory{0}_{1:yyyy-MM-dd_HHmmss}", isTestExport ? "_Test" : string.Empty, exportedAt); if (pageCount > 1) { text += $"_part{pageIndex + 1:D2}of{pageCount:D2}"; } return Path.Combine(exportDirectory, text + (exportAsJpeg ? ".jpg" : ".png")); } private static void SetLayerRecursively(GameObject gameObject, int layer) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) gameObject.layer = layer; foreach (Transform item in gameObject.transform) { SetLayerRecursively(((Component)item).gameObject, layer); } } } internal static class PactHistoryExportSettings { internal static ConfigEntry IncludePactTimestamps { get; private set; } internal static ConfigEntry OutputFormat { get; private set; } internal static ConfigEntry JpegQuality { get; private set; } internal static ConfigEntry JpegTargetSizeMiB { get; private set; } internal static ConfigEntry DebugTestPanelCount { get; private set; } internal static ConfigEntry DebugExportShortcut { get; private set; } internal static void Initialize(ConfigFile config) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) IncludePactTimestamps = config.Bind("Display", "IncludePactTimestamps", true, "Show each pact's in-run acquisition time above its panel in exported images."); OutputFormat = config.Bind("Output", "Format", "png", "Image format: png (lossless) or jpg (smaller lossy files)."); JpegQuality = config.Bind("Output", "JpegQuality", 90, "Initial JPEG quality from 1 to 100. Lower values make smaller files."); JpegTargetSizeMiB = config.Bind("Output", "JpegTargetSizeMiB", 8, "JPEG size target in MiB. The exporter lowers quality down to 50 when necessary; 0 disables the target."); DebugTestPanelCount = config.Bind("Debug", "TestPanelCount", 0, "Development-only test output count. Set above 0 to repeat the current pact snapshots up to this count; 0 disables the test shortcut."); DebugExportShortcut = config.Bind("Debug", "ExportShortcut", new KeyboardShortcut((KeyCode)289, Array.Empty()), "Development-only shortcut for test export. It does nothing while TestPanelCount is 0."); } } [BepInPlugin("io.github.kusyua.lwf.pacthistoryexporter", "LWF Pact History Exporter", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "io.github.kusyua.lwf.pacthistoryexporter"; public const string PluginName = "LWF Pact History Exporter"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; PactHistoryExportSettings.Initialize(((BaseUnityPlugin)this).Config); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LWF Pact History Exporter 1.0.0 loaded."); new Harmony("io.github.kusyua.lwf.pacthistoryexporter").PatchAll(); } private void Update() { //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) if (PactHistoryExportSettings.DebugExportShortcut != null) { KeyboardShortcut value = PactHistoryExportSettings.DebugExportShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { PactHistoryExportService.RequestDebugExport(); } } } } } namespace LwfPactHistoryExporter.Patches { [HarmonyPatch(typeof(PactHistoryUIController))] internal static class PactHistoryExportButtonPatch { private const string ExportButtonName = "LwfPactHistoryExportButton"; [HarmonyPostfix] [HarmonyPatch("Open", new Type[] { typeof(InGameWindowPresentationContext), typeof(Transform), typeof(Action) })] private static void AddExportButton(PactHistoryUIController __instance) { if (Object.op_Implicit((Object)(object)FindExistingExportButton(((Component)__instance).transform))) { return; } object? obj = AccessTools.Field(typeof(PactHistoryUIController), "_backToFactoryButton")?.GetValue(__instance); object? obj2 = ((obj is Button) ? obj : null); Transform obj3 = ((obj2 != null) ? ((Component)obj2).transform : null); RectTransform val = (RectTransform)(object)((obj3 is RectTransform) ? obj3 : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)((Transform)val).parent)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Could not add the pact history export button because the back button layout was not found."); } return; } CellComponents val2 = FindResultButtonTemplate(); if (!Object.op_Implicit((Object)(object)val2)) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"Could not add the pact history export button because the result button template was not found."); } return; } CellComponents obj4 = Object.Instantiate(val2, ((Transform)val).parent); ((Object)obj4).name = "LwfPactHistoryExportButton"; ((Component)obj4).gameObject.SetActive(true); obj4.SetText("Export"); obj4.AssignAction((Action)PactHistoryExportService.RequestExport); obj4.HandleSelectedEffect(false); Transform transform = ((Component)obj4).transform; PlaceBesideBackButton((RectTransform)(object)((transform is RectTransform) ? transform : null), val); } private static void PlaceBesideBackButton(RectTransform exportButtonRect, RectTransform backButtonRect) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) //IL_0077: 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_0082: 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_00a2: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)exportButtonRect)) { exportButtonRect.anchorMin = backButtonRect.anchorMin; exportButtonRect.anchorMax = backButtonRect.anchorMax; exportButtonRect.pivot = backButtonRect.pivot; ((Transform)exportButtonRect).localScale = ((Transform)backButtonRect).localScale; Rect rect = backButtonRect.rect; float num = Mathf.Max(180f, ((Rect)(ref rect)).width * 1.8f); exportButtonRect.SetSizeWithCurrentAnchors((Axis)0, num); rect = backButtonRect.rect; exportButtonRect.SetSizeWithCurrentAnchors((Axis)1, ((Rect)(ref rect)).height); Vector2 anchoredPosition = backButtonRect.anchoredPosition; rect = backButtonRect.rect; exportButtonRect.anchoredPosition = anchoredPosition - new Vector2((((Rect)(ref rect)).width + num) / 2f + 16f, 0f); TextMeshProUGUI componentInChildren = ((Component)exportButtonRect).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)componentInChildren).enableAutoSizing = true; ((TMP_Text)componentInChildren).fontSizeMin = 16f; ((TMP_Text)componentInChildren).fontSizeMax = Mathf.Max(16f, ((TMP_Text)componentInChildren).fontSize); } } } private static Transform FindExistingExportButton(Transform root) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == "LwfPactHistoryExportButton") { return val; } } return null; } private static CellComponents FindResultButtonTemplate() { ResultUIManager obj = Object.FindFirstObjectByType((FindObjectsInactive)1); WindowWithCells val = ((obj != null) ? ((WindowWithCellUIManager)obj).GetWindow() : null); if (val != null) { object? obj2 = AccessTools.Field(typeof(WindowWithCells), "_cellComponents")?.GetValue(val); return (CellComponents)((obj2 is CellComponents) ? obj2 : null); } return null; } } [HarmonyPatch(typeof(PactHistoryStore), "Add")] internal static class PactHistoryStoreAddPatch { private static void Postfix(PactCellSnapshot snapshot) { PactHistoryExportService.RecordPactTimestamp(snapshot); } } [HarmonyPatch(typeof(PactHistoryStore), "Clear")] internal static class PactHistoryStoreClearPatch { private static void Prefix() { PactHistoryExportService.ClearPactTimestamps(); } } }