Decompiled source of LwfPactHistoryExporter v1.0.0

LwfPactHistoryExporter/LwfPactHistoryExporter.dll

Decompiled 3 days ago
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<PactCellSnapshot> 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<string> exportedPaths = new List<string>(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<PactCellSnapshot> 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>();
					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<Canvas>();
					component.renderMode = (RenderMode)1;
					component.worldCamera = camera;
					component.planeDistance = 1f;
					component.pixelPerfect = true;
					canvasObject.GetComponent<CanvasScaler>().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<PactCellComponents>(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<PactCellSnapshot, double> PactElapsedTimes = new Dictionary<PactCellSnapshot, double>();

		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<PactHistoryExportRunner>();
			return _runner;
		}

		private static PactCellComponents FindCellTemplate()
		{
			PactHistoryUIController val = Object.FindFirstObjectByType<PactHistoryUIController>((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<TextMeshProUGUI>(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<TextMeshProUGUI>();
				((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<PactCellSnapshot> CreateTestSnapshots(IReadOnlyList<PactCellSnapshot> snapshots, int requestedCount)
		{
			int num = Mathf.Max(1, requestedCount);
			List<PactCellSnapshot> list = new List<PactCellSnapshot>(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<bool> IncludePactTimestamps { get; private set; }

		internal static ConfigEntry<string> OutputFormat { get; private set; }

		internal static ConfigEntry<int> JpegQuality { get; private set; }

		internal static ConfigEntry<int> JpegTargetSizeMiB { get; private set; }

		internal static ConfigEntry<int> DebugTestPanelCount { get; private set; }

		internal static ConfigEntry<KeyboardShortcut> 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<bool>("Display", "IncludePactTimestamps", true, "Show each pact's in-run acquisition time above its panel in exported images.");
			OutputFormat = config.Bind<string>("Output", "Format", "png", "Image format: png (lossless) or jpg (smaller lossy files).");
			JpegQuality = config.Bind<int>("Output", "JpegQuality", 90, "Initial JPEG quality from 1 to 100. Lower values make smaller files.");
			JpegTargetSizeMiB = config.Bind<int>("Output", "JpegTargetSizeMiB", 8, "JPEG size target in MiB. The exporter lowers quality down to 50 when necessary; 0 disables the target.");
			DebugTestPanelCount = config.Bind<int>("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<KeyboardShortcut>("Debug", "ExportShortcut", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "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<CellComponents>(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<TextMeshProUGUI>(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<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "LwfPactHistoryExportButton")
				{
					return val;
				}
			}
			return null;
		}

		private static CellComponents FindResultButtonTemplate()
		{
			ResultUIManager obj = Object.FindFirstObjectByType<ResultUIManager>((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();
		}
	}
}