Decompiled source of SaveFileManagerMod v0.2.0

SaveFileManagerMod/SaveFileManagerMod.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GlobalEnums;
using HarmonyLib;
using InControl;
using Microsoft.CodeAnalysis;
using SaveFileManagerMod.UI;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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("SaveFileManagerMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+8651f5f47eca83250461bd853bebfe8d19f83489")]
[assembly: AssemblyProduct("SaveFileManagerMod")]
[assembly: AssemblyTitle("SaveFileManagerMod")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/mich101mich/Silksong.SaveFileManagerMod")]
[assembly: NeutralResourcesLanguage("EN")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace SaveFileManagerMod
{
	public class SaveArchive
	{
		public static void ArchiveSlot(int slotIndex, int archiveSlotIndex)
		{
			MoveSlot(slotIndex, archiveSlotIndex);
		}

		public static void LoadSlot(int targetSlotIndex, int archiveSlotIndex)
		{
			MoveSlot(archiveSlotIndex, targetSlotIndex);
		}

		public static void SwapSlots(int slotIndexA, int slotIndexB)
		{
			if (slotIndexA != slotIndexB)
			{
				MoveSlot(slotIndexA, 99999);
				MoveSlot(slotIndexB, slotIndexA);
				MoveSlot(99999, slotIndexB);
			}
		}

		public static void MoveSlot(int sourceSlotIndex, int targetSlotIndex)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			string saveDirPath = ((DesktopPlatform)Platform.Current).saveDirPath;
			string text = $"user{sourceSlotIndex}";
			string text2 = $"user{targetSlotIndex}";
			string[] files = Directory.GetFiles(saveDirPath);
			foreach (string text3 in files)
			{
				string fileName = Path.GetFileName(text3);
				if (fileName.StartsWith(text) && (fileName.Length == text.Length || !char.IsDigit(fileName[text.Length])))
				{
					string targetPath = Path.Combine(saveDirPath, text2 + fileName.Substring(text.Length));
					MovePathInternal(text3, targetPath);
				}
			}
			string sourcePath = Path.Combine(saveDirPath, $"Restore_Points{sourceSlotIndex}");
			string targetPath2 = Path.Combine(saveDirPath, $"Restore_Points{targetSlotIndex}");
			MovePathInternal(sourcePath, targetPath2);
			string moddedSaveDataDir = GetModdedSaveDataDir(sourceSlotIndex);
			string moddedSaveDataDir2 = GetModdedSaveDataDir(targetSlotIndex);
			MovePathInternal(moddedSaveDataDir, moddedSaveDataDir2);
		}

		public static void MovePathInternal(string sourcePath, string targetPath)
		{
			try
			{
				if (Directory.Exists(sourcePath) || File.Exists(sourcePath))
				{
					Directory.Move(sourcePath, targetPath);
					SfmLogger.LogInfo("Moved \nfrom " + sourcePath + "\nto   " + targetPath);
				}
			}
			catch (Exception arg)
			{
				SfmLogger.LogError($"Failed to move \nfrom {sourcePath}\nto   {targetPath}\nreason: {arg}");
			}
		}

		public static string GetModdedSaveDataDir(int slotIndex)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Path.Combine(((DesktopPlatform)Platform.Current).saveDirPath, "Modded", $"user{slotIndex}");
		}
	}
	public class SfmLogger
	{
		public static ManualLogSource? _logger;

		public static void Log(LogLevel level, string message)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (_logger != null)
			{
				string text = DateTime.Now.ToString("HH:mm:ss.fff");
				string text2 = "[" + text + "] " + message;
				ManualLogSource? logger = _logger;
				if (logger != null)
				{
					logger.Log(level, (object)text2);
				}
			}
		}

		public static void LogInfo(string message)
		{
			Log((LogLevel)16, message);
		}

		public static void LogWarning(string message)
		{
			Log((LogLevel)4, message);
		}

		public static void LogError(string message)
		{
			Log((LogLevel)2, message);
		}
	}
	[BepInPlugin("io.github.mich101mich.savefilemanagermod", "SaveFileManagerMod", "0.2.0")]
	public class SaveFileManagerPlugin : BaseUnityPlugin
	{
		public static SaveFileManagerPlugin s_instance;

		public Harmony m_harmony;

		public bool? m_isModCompatible;

		public List<SaveOptions> m_saveOptions = new List<SaveOptions>();

		public ArchiveSlotSelectionMenu m_archiveMenu;

		public const string Id = "io.github.mich101mich.savefilemanagermod";

		public static string Name => "SaveFileManagerMod";

		public static string Version => "0.2.0";

		public void Awake()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			s_instance = this;
			SfmLogger._logger = ((BaseUnityPlugin)this).Logger;
			SfmLogger.LogInfo("Plugin " + Name + " (io.github.mich101mich.savefilemanagermod) v" + Version + " has loaded!");
			m_archiveMenu = ((Component)this).gameObject.AddComponent<ArchiveSlotSelectionMenu>();
			m_harmony = new Harmony("harmony-io.github.mich101mich.savefilemanagermod");
			m_harmony.PatchAll(typeof(SaveFileManagerPlugin));
		}

		public void OnDestroy()
		{
			SfmLogger.LogInfo("Plugin " + Name + " (io.github.mich101mich.savefilemanagermod) is unloading...");
			m_harmony.UnpatchSelf();
			foreach (SaveOptions saveOption in m_saveOptions)
			{
				Object.Destroy((Object)(object)saveOption);
			}
			m_saveOptions.Clear();
			s_instance = null;
			SfmLogger._logger = null;
		}

		public bool IsModCompatible()
		{
			if (!m_isModCompatible.HasValue)
			{
				Platform current = Platform.Current;
				DesktopPlatform val = (DesktopPlatform)(object)((current is DesktopPlatform) ? current : null);
				if (val != null)
				{
					if (val.onlineSubsystem != null && val.onlineSubsystem.HandlesGameSaves)
					{
						SfmLogger.LogError($"SaveFileManagerMod: This mod is not compatible with the online subsystem {val.onlineSubsystem}.");
						m_isModCompatible = false;
					}
					m_isModCompatible = true;
				}
				else
				{
					SfmLogger.LogError($"SaveFileManagerMod: Unsupported platform {Platform.Current}. This mod only works on desktop platforms.");
					m_isModCompatible = false;
				}
			}
			return m_isModCompatible.Value;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UIManager), "UIGoToProfileMenu")]
		public static void UIManager_UIGoToProfileMenu_Prefix(UIManager __instance)
		{
			s_instance.InitUi();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UIManager), "MakeMenuLean")]
		public static void UIManager_MakeMenuLean_Prefix(UIManager __instance)
		{
			s_instance.m_saveOptions.Clear();
		}

		public void InitUi()
		{
			if (m_saveOptions.Count <= 0 && IsModCompatible())
			{
				SfmLogger.LogInfo("Initializing SaveOptions for all save slots...");
				UIManager instance = UIManager.instance;
				SaveSlotButton[] array = (SaveSlotButton[])(object)new SaveSlotButton[4] { instance.slotOne, instance.slotTwo, instance.slotThree, instance.slotFour };
				foreach (SaveSlotButton val in array)
				{
					SaveOptions saveOptions = ((Component)val).gameObject.AddComponent<SaveOptions>();
					saveOptions.Initialize(val);
					m_saveOptions.Add(saveOptions);
				}
				for (int j = 0; j < m_saveOptions.Count; j++)
				{
					SaveOptions previousOptions = ((j - 1 >= 0) ? m_saveOptions[j - 1] : null);
					SaveOptions nextOptions = ((j + 1 < m_saveOptions.Count) ? m_saveOptions[j + 1] : null);
					m_saveOptions[j].SetupNavigation(previousOptions, nextOptions);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveSlotButton), "Prepare")]
		public static void SaveSlotButton_Prepare_Postfix(SaveSlotButton __instance)
		{
			if (s_instance.IsModCompatible())
			{
				SaveName.ReloadSlot(__instance.SaveSlotIndex);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveSlotButton), "UpdateSaveFileState")]
		public static void SaveSlotButton_UpdateSaveFileState_Postfix(SaveSlotButton __instance)
		{
			if (s_instance.IsModCompatible())
			{
				SaveName.ReloadSlot(__instance.SaveSlotIndex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SaveSlotButton), "ChangeSaveFileState")]
		public static void SaveSlotButton_ChangeSaveFileState_Prefix(SaveSlotButton __instance, SaveFileStates nextSaveFileState)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (s_instance.IsModCompatible() && (int)nextSaveFileState == 2)
			{
				SaveName.ClearSlot(__instance.SaveSlotIndex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Selectable), "OnMove")]
		public static void RestoreSaveButton_OnMove_Prefix(Selectable __instance, AxisEventData eventData, ref bool __runOriginal)
		{
			if (__instance is RestoreSaveButton && __runOriginal && SaveSlotActionButton.TryNavigateSkippingDisabled(eventData, __instance))
			{
				__runOriginal = false;
			}
		}
	}
	public class SaveName
	{
		public static Dictionary<int, string> Names = new Dictionary<int, string>();

		public static bool TryGetSlotName(int slotIndex, out string name)
		{
			if (Names.TryGetValue(slotIndex, out name))
			{
				return !string.IsNullOrWhiteSpace(name);
			}
			return false;
		}

		public static bool GetOrLoadSlotName(int slotIndex, out string name)
		{
			if (TryGetSlotName(slotIndex, out name))
			{
				return true;
			}
			ReloadSlot(slotIndex);
			return TryGetSlotName(slotIndex, out name);
		}

		public static void SetSlotName(int slotIndex, string name)
		{
			string text = name.Trim();
			Names[slotIndex] = text;
			string nameFilePath = GetNameFilePath(slotIndex);
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(nameFilePath));
				File.WriteAllText(nameFilePath, text);
				SfmLogger.LogInfo($"Saved name \"{text}\" for slot {slotIndex} to {nameFilePath}");
			}
			catch (Exception ex)
			{
				SfmLogger.LogError($"Error saving name for slot {slotIndex} to {nameFilePath}: {ex.Message}");
			}
		}

		public static void ReloadSlot(int slotIndex)
		{
			string nameFilePath = GetNameFilePath(slotIndex);
			try
			{
				string text = File.ReadAllText(nameFilePath).Trim();
				Names[slotIndex] = text;
				SfmLogger.LogInfo($"Loaded name \"{text}\" for slot {slotIndex}");
				return;
			}
			catch (DirectoryNotFoundException)
			{
			}
			catch (FileNotFoundException)
			{
			}
			catch (Exception ex3)
			{
				SfmLogger.LogError($"Error loading name for slot {slotIndex} from {nameFilePath}: {ex3.Message}");
			}
			string legacyNameFilePath = GetLegacyNameFilePath(slotIndex);
			try
			{
				string text2 = File.ReadAllText(legacyNameFilePath).Trim();
				Names[slotIndex] = text2;
				SfmLogger.LogInfo($"Loaded legacy name \"{text2}\" for slot {slotIndex}");
				SetSlotName(slotIndex, text2);
				File.Delete(legacyNameFilePath);
				return;
			}
			catch (DirectoryNotFoundException)
			{
			}
			catch (FileNotFoundException)
			{
			}
			catch (Exception ex6)
			{
				SfmLogger.LogError($"Error loading legacy name for slot {slotIndex} from {legacyNameFilePath}: {ex6.Message}");
			}
			Names[slotIndex] = string.Empty;
		}

		public static void ClearSlot(int slotIndex)
		{
			Names[slotIndex] = string.Empty;
			string nameFilePath = GetNameFilePath(slotIndex);
			try
			{
				File.Delete(nameFilePath);
			}
			catch (Exception)
			{
			}
			string legacyNameFilePath = GetLegacyNameFilePath(slotIndex);
			try
			{
				File.Delete(legacyNameFilePath);
			}
			catch (Exception)
			{
			}
		}

		public static string GetNameFilePath(int slotIndex)
		{
			return Path.Combine(SaveArchive.GetModdedSaveDataDir(slotIndex), "sfm_save_name.txt.dat");
		}

		public static string GetLegacyNameFilePath(int slotIndex)
		{
			return Path.Combine(SaveArchive.GetModdedSaveDataDir(slotIndex), "SaveData", "sfm_save_name.txt.dat");
		}
	}
}
namespace SaveFileManagerMod.UI
{
	public class ActionButtonWrapper
	{
		public readonly MenuButton button;

		public readonly CanvasGroup canvasGroup;

		public readonly RectTransform rectTransform;

		public readonly bool isOriginal;

		public bool canUse;

		public ActionButtonWrapper(MenuButton button, bool isOriginal)
		{
			this.button = button;
			canvasGroup = ((Component)button).GetComponent<CanvasGroup>();
			rectTransform = ((Component)button).GetComponent<RectTransform>();
			this.isOriginal = isOriginal;
			canUse = false;
		}

		public bool IsUsable()
		{
			if ((Object)(object)button != (Object)null && ((UIBehaviour)button).IsActive())
			{
				return ((Selectable)button).IsInteractable();
			}
			return false;
		}

		public void SetUsable(bool usable)
		{
			if (canUse == usable)
			{
				return;
			}
			canUse = usable;
			if (!isOriginal)
			{
				((Selectable)button).interactable = usable;
				canvasGroup.interactable = usable;
				if (usable)
				{
					((MonoBehaviour)UIManager.instance).StartCoroutine(FadeInAfterDelay(0.1f));
				}
				else
				{
					((MonoBehaviour)UIManager.instance).StartCoroutine(FadeOutAfterDelay(0.1f));
				}
			}
		}

		public void SetVisibility(bool visible, bool focus = false)
		{
			UIManager instance = UIManager.instance;
			if (visible)
			{
				if (canUse)
				{
					if (focus)
					{
						((MonoBehaviour)instance).StartCoroutine(FadeInAndFocus());
					}
					else
					{
						((MonoBehaviour)instance).StartCoroutine(instance.FadeInCanvasGroup(canvasGroup, false));
					}
				}
			}
			else
			{
				((MonoBehaviour)instance).StartCoroutine(instance.FadeOutCanvasGroup(canvasGroup, true, false));
			}
		}

		public IEnumerator FadeInAfterDelay(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			yield return UIManager.instance.FadeInCanvasGroup(canvasGroup, false);
			canvasGroup.blocksRaycasts = true;
		}

		public IEnumerator FadeOutAfterDelay(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			canvasGroup.blocksRaycasts = false;
			yield return UIManager.instance.FadeOutCanvasGroup(canvasGroup, true, false);
		}

		public IEnumerator FadeInAndFocus()
		{
			yield return UIManager.instance.FadeInCanvasGroup(canvasGroup, false);
			canvasGroup.blocksRaycasts = true;
			EventSystem current = EventSystem.current;
			if (current != null)
			{
				current.SetSelectedGameObject(((Component)button).gameObject);
			}
		}
	}
	public class ArchiveMenuEntry : IDisposable
	{
		public class Strings : StringHelper
		{
			public static string Error => StringHelper.Get("ArchiveMenuEntry.Error", "Error");

			public static string Unnamed => StringHelper.Get("ArchiveMenuEntry.Unnamed", "Unnamed");

			public static string Empty => StringHelper.Get("ArchiveMenuEntry.Empty", "Empty");
		}

		public static readonly float SLOT_TEXT_HEIGHT = 70f;

		public static readonly float SLOT_PREVIEW_HEIGHT = 140f;

		public static readonly float SLOT_TOTAL_HEIGHT = SLOT_TEXT_HEIGHT + SLOT_PREVIEW_HEIGHT;

		public static readonly float SLOT_WIDTH = 1182f;

		public SaveProfileHealthBar? m_healthSlots;

		public SaveProfileSilkBar? m_silkBar;

		public readonly GameObject Container;

		public readonly MenuButton MenuButton;

		public readonly Text ButtonText;

		public readonly Text DescriptionText;

		public Action? OnSubmit;

		private bool m_disposed;

		public ArchiveMenuEntry(int slotIndex, SaveStats? stats, string? message, SaveSlotButton template)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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)
			//IL_00f3: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			GameObject? child = SfmUtil.GetChild(((Component)UIManager.instance).gameObject, "UICanvas");
			GameObject child2 = SfmUtil.GetChild(child, "OptionsMenuScreen/Content/GameOptions");
			Container = Object.Instantiate<GameObject>(child2, child2.transform.parent, false);
			((Object)Container).name = "SFM-ArchiveSaveSlot";
			Container.GetComponent<RectTransform>().sizeDelta = new Vector2(SLOT_WIDTH, SLOT_TOTAL_HEIGHT);
			GameObject child3 = SfmUtil.GetChild(Container, "GameOptionsButton");
			((Object)child3).name = "SFM-ArchiveSaveSlot-Inner";
			SfmUtil.RemoveComponent<AutoLocalizeTextUI>(child3);
			SfmUtil.RemoveComponent<EventTrigger>(child3);
			GameObject child4 = SfmUtil.GetChild(child3, "Menu Button Text");
			((Object)child4).name = "SFM-SaveSlotName";
			SfmUtil.RemoveComponent<ChangeTextFontScaleOnHandHeld>(child4);
			SfmUtil.RemoveComponent<ContentSizeFitter>(child4);
			RectTransform component = child4.GetComponent<RectTransform>();
			component.pivot = new Vector2(0.5f, 1f);
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(SLOT_WIDTH, SLOT_TEXT_HEIGHT);
			ButtonText = child4.GetComponent<Text>();
			ButtonText.text = Init(slotIndex, stats, message);
			ButtonText.alignment = (TextAnchor)3;
			GameObject val = Object.Instantiate<GameObject>(SfmUtil.GetChild(child, "GameOptionsMenuScreen/Content/CamShakeSetting/CamShakePopupOption/Description"), child3.transform, false);
			((Object)val).name = ((message != null) ? "SFM-SaveSlotDescription" : "SFM-SaveSlotPreview");
			SfmUtil.RemoveComponent<ChangeTextFontScaleOnHandHeld>(val);
			DescriptionText = val.GetComponent<Text>();
			DescriptionText.text = message ?? "";
			DescriptionText.alignment = (TextAnchor)4;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0.5f);
			component2.anchorMax = new Vector2(0.5f, 0.5f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			MenuButton = child3.GetComponent<MenuButton>();
			MenuButton.buttonType = (MenuButtonType)1;
			((MenuSelectable)MenuButton).descriptionText = val.GetComponent<Animator>();
			MenuButton.OnSubmitPressed = new UnityEvent();
			if (message == null)
			{
				MenuButton.OnSubmitPressed.AddListener((UnityAction)delegate
				{
					OnSubmit?.Invoke();
				});
			}
			if (message == null && stats != null)
			{
				SfmUtil.RemoveComponent<ChangePositionByLanguage>(val);
				RectTransform component3 = val.GetComponent<RectTransform>();
				component3.pivot = new Vector2(0.5f, 1f);
				component3.anchorMin = new Vector2(0.5f, 1f);
				component3.anchorMax = new Vector2(0.5f, 1f);
				component3.anchoredPosition = new Vector2(0f, 0f - SLOT_TEXT_HEIGHT);
				component3.sizeDelta = new Vector2(SLOT_WIDTH, SLOT_PREVIEW_HEIGHT);
				CloneSaveSlotElements(val, slotIndex, stats, template);
			}
		}

		public void Dispose()
		{
			if (!m_disposed)
			{
				m_disposed = true;
				((UnityEventBase)MenuButton.OnSubmitPressed).RemoveAllListeners();
				Object.Destroy((Object)(object)Container);
			}
		}

		public static string Init(int slotIndex, SaveStats? stats, string? message)
		{
			if (message != null)
			{
				return $"{slotIndex}. <{Strings.Error}>";
			}
			if (stats != null)
			{
				if (SaveName.GetOrLoadSlotName(slotIndex, out string name))
				{
					return $"{slotIndex}. {name}";
				}
				return $"{slotIndex}. <{Strings.Unnamed}>";
			}
			return $"{slotIndex}. <{Strings.Empty}>";
		}

		public void CloneSaveSlotElements(GameObject preview, int slotIndex, SaveStats stats, SaveSlotButton template)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0122: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Expected O, but got Unknown
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Invalid comparison between Unknown and I4
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Invalid comparison between Unknown and I4
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			(GameObject obj, RectTransform transform) tuple = CloneChild(preview, template, "ActiveSaveSlot/HUDLayout/Health Bar/Spool Icon");
			GameObject item = tuple.obj;
			RectTransform item2 = tuple.transform;
			(GameObject obj, RectTransform transform) tuple2 = CloneChild(preview, template, "ActiveSaveSlot/HUDLayout/Health Bar/HealthSlots");
			GameObject item3 = tuple2.obj;
			RectTransform item4 = tuple2.transform;
			(GameObject obj, RectTransform transform) tuple3 = CloneChild(preview, template, "DefeatedText");
			GameObject item5 = tuple3.obj;
			RectTransform item6 = tuple3.transform;
			(GameObject obj, RectTransform transform) tuple4 = CloneChild(preview, template, "ActiveSaveSlot/HUDLayout/Thread Spool");
			GameObject item7 = tuple4.obj;
			RectTransform item8 = tuple4.transform;
			RectTransform item9 = CloneChild(preview, template, "ActiveSaveSlot/HUDLayout/Rosaries").transform;
			RectTransform item10 = CloneChild(preview, template, "ActiveSaveSlot/HUDLayout/Shell Shards").transform;
			var (val, val2) = CloneChild(preview, template, "ActiveSaveSlot/Bottom Section/PlayTimeText");
			var (val3, val4) = CloneChild(preview, template, "ActiveSaveSlot/Bottom Section/CompletionText");
			var (val5, val6) = CloneChild(preview, template, "ActiveSaveSlot/Bottom Section/LocationText");
			((LayoutGroup)item3.GetComponent<GridLayoutGroup>()).padding = new RectOffset(0, 0, 0, 0);
			float num = ((stats.MaxHealth > 5) ? 100f : 50f);
			item4.sizeDelta = new Vector2(220f, num);
			item6.sizeDelta = new Vector2(480f, 70f);
			item2.anchoredPosition = new Vector2(-45f, 0f);
			item4.anchoredPosition = new Vector2(155f, 0f);
			item6.anchoredPosition = new Vector2(155f, 0f);
			item8.anchoredPosition = new Vector2(370f, 0f);
			item9.anchoredPosition = new Vector2(630f, 35f);
			item10.anchoredPosition = new Vector2(630f, -35f);
			val2.anchoredPosition = new Vector2(870f, 35f);
			val6.anchoredPosition = new Vector2(870f, -35f);
			val4.anchoredPosition = new Vector2(890f, 35f);
			Image[] componentsInChildren = ((Component)item4).GetComponentsInChildren<Image>(true);
			m_healthSlots = new SaveProfileHealthBar
			{
				crests = template.healthSlots.crests,
				spoolImage = item.GetComponent<Image>(),
				healthTemplate = componentsInChildren[0]
			};
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				m_healthSlots.healthImages.Add(componentsInChildren[i]);
			}
			Transform val7 = ((Transform)item8).Find("Rod Sizer/Inside/Silk Chunk") ?? ((Transform)item8).Find("Rod Sizer/Silk Chunk");
			m_silkBar = new SaveProfileSilkBar
			{
				sizer = SfmUtil.GetChildComponent<LayoutElement>(item7, "Rod Sizer"),
				widthPerSilk = template.silkBar.widthPerSilk,
				baseWidth = template.silkBar.baseWidth,
				silkChunkTemplate = ((Component)val7).gameObject.GetComponent<Image>(),
				silkChunkVariants = template.silkBar.silkChunkVariants,
				silkChunkParent = ((Transform)item8).Find("Rod Sizer/Inside"),
				notBroken = SfmUtil.GetChild(item7, "Rod Sizer/NotBroken"),
				brokenAlt = SfmUtil.GetChild(item7, "Rod Sizer/Broken"),
				cursedAlt = SfmUtil.GetChild(item7, "Rod Sizer/Broken Cursed")
			};
			if ((int)stats.PermadeathMode == 2)
			{
				m_healthSlots.ShowHealth(0, true, stats.CrestId);
				item7.SetActive(false);
				item5.SetActive(true);
				item5.GetComponent<Text>().alignment = (TextAnchor)0;
				item5.GetComponent<CanvasGroup>().alpha = 1f;
			}
			else
			{
				bool flag = (int)stats.PermadeathMode == 1;
				m_healthSlots.ShowHealth(stats.MaxHealth, flag, stats.CrestId);
				m_silkBar.ShowSilk(stats.IsSpoolBroken, stats.MaxSilk, stats.CrestId == "Cursed");
				item5.SetActive(false);
			}
			Transform obj = ((Transform)item9).Find("Text");
			Text obj2 = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null);
			obj2.text = stats.Geo.ToString();
			obj2.fontSize = 40;
			Transform obj3 = ((Transform)item10).Find("Text");
			Text obj4 = ((obj3 != null) ? ((Component)obj3).GetComponent<Text>() : null);
			obj4.text = stats.Shards.ToString();
			obj4.fontSize = 40;
			Text component = val.GetComponent<Text>();
			component.text = stats.GetPlaytimeHHMM();
			component.alignment = (TextAnchor)3;
			if (stats.UnlockedCompletionRate)
			{
				Text component2 = val3.GetComponent<Text>();
				component2.text = stats.CompletionPercentage.ToString(CultureInfo.InvariantCulture) + "%";
				component2.alignment = (TextAnchor)5;
				component2.fontSize = 40;
			}
			else
			{
				val3.SetActive(false);
			}
			string text;
			if (stats.IsBlackThreadInfected)
			{
				text = "???";
			}
			else
			{
				LocalisedString? val8 = template.saveSlots.GetBackground(stats)?.NameOverride;
				if (val8.HasValue)
				{
					LocalisedString valueOrDefault = val8.GetValueOrDefault();
					if (!((LocalisedString)(ref valueOrDefault)).IsEmpty)
					{
						text = LocalisedString.op_Implicit(valueOrDefault);
						goto IL_0508;
					}
				}
				text = GameManager.GetFormattedMapZoneStringV2(stats.MapZone);
			}
			goto IL_0508;
			IL_0508:
			Text component3 = val5.GetComponent<Text>();
			component3.text = text;
			component3.alignment = (TextAnchor)3;
			component3.fontSize = 40;
		}

		public (GameObject obj, RectTransform transform) CloneChild(GameObject target, SaveSlotButton slot, string childPath)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			GameObject gameObject = ((Component)slot).gameObject;
			int num = childPath.LastIndexOf('/');
			string text = ((num >= 0) ? childPath.Substring(num + 1) : childPath);
			GameObject child = SfmUtil.GetChild(gameObject, childPath);
			if ((Object)(object)child == (Object)null)
			{
				GameObject val = new GameObject("MissingChild-" + text);
				RectTransform item = val.AddComponent<RectTransform>();
				return (obj: val, transform: item);
			}
			GameObject obj = Object.Instantiate<GameObject>(child, target.transform);
			((Object)obj).name = text;
			obj.SetActive(true);
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0.5f);
			component.anchorMax = new Vector2(0f, 0.5f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.pivot = new Vector2(0f, 0.5f);
			return (obj: obj, transform: component);
		}
	}
	public sealed class ArchiveMenuScreen : IDisposable
	{
		public GameObject m_container;

		public MenuScreen m_menuScreen;

		public ScrollRect m_scrollRect;

		public RectTransform m_content;

		public RectTransform m_viewport;

		public Slider m_verticalSlider;

		public MenuButton m_backButton;

		public Coroutine? m_scrollRoutine;

		public List<ArchiveMenuEntry> m_entries = new List<ArchiveMenuEntry>();

		public bool m_disposed;

		public static readonly float SCROLL_TIME_SECONDS = 0.2f;

		public ArchiveMenuScreen(string title, string statusMessage, Action onGoBack, out Text statusText)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_016d: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			ArchiveMenuScreen archiveMenuScreen = this;
			GameObject child = SfmUtil.GetChild(((Component)UIManager.instance).gameObject, "UICanvas");
			GameObject child2 = SfmUtil.GetChild(child, "OptionsMenuScreen");
			m_container = Object.Instantiate<GameObject>(child2, child.transform, false);
			((Object)m_container).name = "SFM-ArchiveSlotSelectionMenu";
			m_container.SetActive(false);
			SfmUtil.RemoveComponentImmediate<MenuButtonList>(m_container);
			Object.DestroyImmediate((Object)(object)SfmUtil.GetChild(m_container, "Content"));
			Text? childComponent = SfmUtil.GetChildComponent<Text>(m_container, "Title");
			SfmUtil.RemoveComponent<AutoLocalizeTextUI>(((Component)childComponent).gameObject);
			childComponent.text = title;
			m_menuScreen = m_container.GetComponent<MenuScreen>();
			m_backButton = SfmUtil.GetChildComponent<MenuButton>(m_container, "Controls/ApplyButton");
			SfmUtil.RemoveComponent<EventTrigger>(((Component)m_backButton).gameObject);
			m_backButton.OnSubmitPressed = new UnityEvent();
			m_backButton.OnSubmitPressed.AddListener((UnityAction)delegate
			{
				onGoBack();
			});
			m_menuScreen.backButton = m_backButton;
			GameObject val = new GameObject("SFM-ArchiveScrollPane")
			{
				layer = m_container.layer
			};
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(m_container.transform, false);
			val2.anchorMin = new Vector2(0.5f, 1f);
			val2.anchorMax = new Vector2(0.5f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.anchoredPosition = new Vector2(0f, -330f);
			val2.sizeDelta = new Vector2(1510f, 875f);
			GameObject val3 = new GameObject("Viewport")
			{
				layer = m_container.layer
			};
			m_viewport = val3.AddComponent<RectTransform>();
			((Transform)m_viewport).SetParent((Transform)(object)val2, false);
			FitToParent(m_viewport);
			Image obj = val3.AddComponent<Image>();
			((Graphic)obj).color = Color.clear;
			((Graphic)obj).raycastTarget = true;
			val3.AddComponent<RectMask2D>();
			GameObject val4 = new GameObject("Content")
			{
				layer = m_container.layer
			};
			m_content = val4.AddComponent<RectTransform>();
			((Transform)m_content).SetParent((Transform)(object)m_viewport, false);
			m_content.anchorMin = new Vector2(0.5f, 1f);
			m_content.anchorMax = new Vector2(0.5f, 1f);
			m_content.pivot = new Vector2(0.5f, 1f);
			m_content.anchoredPosition = Vector2.zero;
			m_content.sizeDelta = new Vector2(ArchiveMenuEntry.SLOT_WIDTH, 0f);
			m_scrollRect = val.AddComponent<ScrollRect>();
			m_scrollRect.horizontal = false;
			m_scrollRect.vertical = true;
			m_scrollRect.movementType = (MovementType)2;
			m_scrollRect.scrollSensitivity = 80f;
			m_scrollRect.viewport = m_viewport;
			m_scrollRect.content = m_content;
			m_scrollRect.verticalNormalizedPosition = 1f;
			m_verticalSlider = CreateVerticalSlider(val2);
			((UnityEvent<float>)(object)m_verticalSlider.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
			{
				if (!Mathf.Approximately(archiveMenuScreen.m_scrollRect.verticalNormalizedPosition, value))
				{
					archiveMenuScreen.m_scrollRect.verticalNormalizedPosition = value;
				}
			});
			((UnityEvent<Vector2>)(object)m_scrollRect.onValueChanged).AddListener((UnityAction<Vector2>)delegate(Vector2 position)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				archiveMenuScreen.m_verticalSlider.SetValueWithoutNotify(position.y);
			});
			statusText = CreateStatusLabel(statusMessage);
		}

		public Text CreateStatusLabel(string text)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(SfmUtil.GetChild(((Component)UIManager.instance).gameObject, "UICanvas/OptionsMenuScreen/Content/GameOptions/GameOptionsButton/Menu Button Text"), (Transform)(object)m_content, false);
			((Object)obj).name = "SFM-StatusLabel";
			obj.SetActive(true);
			SfmUtil.RemoveComponent<ChangeTextFontScaleOnHandHeld>(obj);
			SfmUtil.RemoveComponent<FixVerticalAlign>(obj);
			Text component = obj.GetComponent<Text>();
			((Graphic)component).raycastTarget = false;
			component.lineSpacing = 1f;
			component.text = text;
			RectTransform component2 = obj.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 1f);
			component2.anchorMax = new Vector2(0.5f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.anchoredPosition = Vector2.zero;
			component2.sizeDelta = new Vector2(ArchiveMenuEntry.SLOT_WIDTH, ArchiveMenuEntry.SLOT_TOTAL_HEIGHT);
			UpdateLayout();
			return component;
		}

		public void Add(ArchiveMenuEntry entry)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			if (m_disposed)
			{
				entry.Dispose();
				return;
			}
			m_entries.Add(entry);
			entry.Container.transform.SetParent((Transform)(object)m_content, false);
			entry.Container.SetActive(true);
			EventTrigger val = ((Component)entry.MenuButton).gameObject.AddComponent<EventTrigger>();
			Entry val2 = new Entry();
			val2.eventID = (EventTriggerType)9;
			((UnityEvent<BaseEventData>)(object)val2.callback).AddListener((UnityAction<BaseEventData>)delegate(BaseEventData data)
			{
				if (data is AxisEventData)
				{
					UIManager instance = UIManager.instance;
					if (m_scrollRoutine != null)
					{
						((MonoBehaviour)instance).StopCoroutine(m_scrollRoutine);
						m_scrollRoutine = null;
					}
					m_scrollRoutine = ((MonoBehaviour)instance).StartCoroutine(ScrollIntoView(entry));
					UIManager.instance.inputModule.focusOnMouseHover = false;
				}
			});
			val.triggers.Add(val2);
			(EventTriggerType, Action<PointerEventData>)[] array = new(EventTriggerType, Action<PointerEventData>)[5]
			{
				((EventTriggerType)7, (Action<PointerEventData>)m_scrollRect.OnScroll),
				((EventTriggerType)5, (Action<PointerEventData>)m_scrollRect.OnDrag),
				((EventTriggerType)13, (Action<PointerEventData>)m_scrollRect.OnBeginDrag),
				((EventTriggerType)14, (Action<PointerEventData>)m_scrollRect.OnEndDrag),
				((EventTriggerType)12, (Action<PointerEventData>)m_scrollRect.OnInitializePotentialDrag)
			};
			for (int num = 0; num < array.Length; num++)
			{
				(EventTriggerType, Action<PointerEventData>) tuple = array[num];
				EventTriggerType item = tuple.Item1;
				Action<PointerEventData> callback = tuple.Item2;
				Entry val3 = new Entry();
				val3.eventID = item;
				((UnityEvent<BaseEventData>)(object)val3.callback).AddListener((UnityAction<BaseEventData>)delegate(BaseEventData data)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Expected O, but got Unknown
					callback((PointerEventData)data);
				});
				val.triggers.Add(val3);
			}
			UpdateLayout();
		}

		public IEnumerator Show()
		{
			UpdateLayout();
			EventSystem current = EventSystem.current;
			if (current != null)
			{
				current.SetSelectedGameObject((GameObject)null);
			}
			m_container.SetActive(true);
			yield return UIManager.instance.ShowMenu(m_menuScreen);
		}

		public IEnumerator Hide()
		{
			yield return UIManager.instance.HideMenu(m_menuScreen, true);
			m_container.SetActive(false);
		}

		public void Dispose()
		{
			if (!m_disposed)
			{
				m_disposed = true;
				if (m_scrollRoutine != null)
				{
					((MonoBehaviour)UIManager.instance).StopCoroutine(m_scrollRoutine);
					m_scrollRoutine = null;
					UIManager.instance.inputModule.focusOnMouseHover = true;
				}
				Object.Destroy((Object)(object)m_container);
			}
		}

		public IEnumerator ScrollIntoView(ArchiveMenuEntry entry)
		{
			float startY = m_scrollRect.verticalNormalizedPosition;
			for (float time = 0f; time < SCROLL_TIME_SECONDS; time += Time.unscaledDeltaTime)
			{
				Rect rect = m_scrollRect.viewport.rect;
				Vector2 size = ((Rect)(ref rect)).size;
				rect = m_scrollRect.content.rect;
				Vector2 size2 = ((Rect)(ref rect)).size;
				float num = Mathf.Clamp01((((Transform)m_scrollRect.content).InverseTransformPoint(entry.Container.transform.position).y + size2.y - size.y * 0.5f) / (size2.y - size.y));
				num = Mathf.Lerp(startY, num, time / SCROLL_TIME_SECONDS);
				m_scrollRect.verticalNormalizedPosition = num;
				yield return null;
			}
			UIManager.instance.inputModule.focusOnMouseHover = true;
		}

		public void UpdateLayout()
		{
			//IL_0025: 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_004f: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < m_entries.Count; i++)
			{
				RectTransform component = m_entries[i].Container.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, (float)(-(i + 1)) * ArchiveMenuEntry.SLOT_TOTAL_HEIGHT);
			}
			float num = m_entries.Count + 1;
			m_content.sizeDelta = new Vector2(ArchiveMenuEntry.SLOT_WIDTH, num * ArchiveMenuEntry.SLOT_TOTAL_HEIGHT);
			RebuildNavigation();
			Canvas.ForceUpdateCanvases();
		}

		public void RebuildNavigation()
		{
			//IL_002a: 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_0052: 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_00fb: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			Navigation navigation;
			if (m_entries.Count == 0)
			{
				m_menuScreen.defaultHighlight = (Selectable)(object)m_backButton;
				MenuButton backButton = m_backButton;
				navigation = ((Selectable)m_backButton).navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)m_backButton;
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)m_backButton;
				((Selectable)backButton).navigation = navigation;
				return;
			}
			for (int i = 0; i < m_entries.Count; i++)
			{
				MenuButton menuButton = m_entries[i].MenuButton;
				navigation = default(Navigation);
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)((i == 0) ? m_backButton : m_entries[i - 1].MenuButton);
				((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)((i == m_entries.Count - 1) ? m_backButton : m_entries[i + 1].MenuButton);
				((Selectable)menuButton).navigation = navigation;
			}
			MenuButton backButton2 = m_backButton;
			navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)4;
			((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)m_entries.Last().MenuButton;
			((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)m_entries.First().MenuButton;
			((Selectable)backButton2).navigation = navigation;
			m_menuScreen.defaultHighlight = (Selectable)(object)m_entries.First().MenuButton;
		}

		public static void FitToParent(RectTransform transform)
		{
			//IL_0001: 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_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			transform.anchorMin = Vector2.zero;
			transform.anchorMax = Vector2.one;
			transform.pivot = new Vector2(0.5f, 0.5f);
			transform.anchoredPosition = Vector2.zero;
			transform.sizeDelta = Vector2.zero;
		}

		public static Slider CreateVerticalSlider(RectTransform scrollTransform)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00a6: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(SfmUtil.GetChild(((Component)UIManager.instance.achievementsMenuScreen).gameObject, "Content/Scrollbar"), (Transform)(object)scrollTransform, false);
			((Object)obj).name = "Scrollbar";
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(50f, 0f);
			RectTransform? childComponent = SfmUtil.GetChildComponent<RectTransform>(obj, "Background");
			childComponent.anchorMin = new Vector2(childComponent.anchorMin.x, 0f);
			childComponent.anchorMax = new Vector2(childComponent.anchorMax.x, 1f);
			childComponent.anchoredPosition = new Vector2(childComponent.anchoredPosition.x, 0f);
			childComponent.sizeDelta = new Vector2(childComponent.sizeDelta.x, 0f);
			RectTransform childComponent2 = SfmUtil.GetChildComponent<RectTransform>(obj, "Sliding Area");
			FitToParent(childComponent2);
			childComponent2.sizeDelta = new Vector2(0f, -150f);
			GameObject? child = SfmUtil.GetChild(obj, "Sliding Area/Handle");
			GameObject? child2 = SfmUtil.GetChild(child, "TopFleur");
			SfmUtil.RemoveComponentImmediate<ScrollBarHandle>(child2);
			RectTransform component2 = child2.GetComponent<RectTransform>();
			Extensions.SetParentReset((Transform)(object)component2, (Transform)(object)childComponent2);
			component2.anchorMin = new Vector2(0f, 0.5f);
			component2.anchorMax = new Vector2(1f, 0.5f);
			component2.pivot = new Vector2(0.5f, 0.5f);
			component2.anchoredPosition = Vector2.zero;
			component2.sizeDelta = new Vector2(0f, 140f);
			((Object)child2).name = "Handle";
			Object.DestroyImmediate((Object)(object)child);
			SfmUtil.RemoveComponentImmediate<Scrollbar>(obj);
			Slider obj2 = obj.AddComponent<Slider>();
			obj2.handleRect = component2;
			obj2.direction = (Direction)2;
			obj2.minValue = 0f;
			obj2.maxValue = 1f;
			obj2.SetValueWithoutNotify(1f);
			return obj2;
		}
	}
	public class ArchiveSlotSelectionMenu : MonoBehaviour
	{
		public class Strings : StringHelper
		{
			public static string TitleLoadIntoEmpty => StringHelper.Get("ArchiveSlotSelectionMenu.TitleLoadIntoEmpty", "Load from archive");

			public static string TitleArchiveSwap => StringHelper.Get("ArchiveSlotSelectionMenu.TitleArchiveSwap", "Archive / Swap");

			public static string LoadingText => StringHelper.Get("ArchiveSlotSelectionMenu.LoadingText", "Loading save slots...");

			public static string NoLoadableSavesFound => StringHelper.Get("ArchiveSlotSelectionMenu.NoLoadableSavesFound", "No loadable saves found");

			public static string NamedSlotInfo(string name, int index)
			{
				return StringHelper.Get("ArchiveSlotSelectionMenu.NamedSlotInfo", "Target: Slot {index}. \"{name}\"", new { name, index });
			}

			public static string UnnamedSlotInfo(int index)
			{
				return StringHelper.Get("ArchiveSlotSelectionMenu.UnnamedSlotInfo", "Target: Slot {index}.", new { index });
			}
		}

		public ArchiveMenuScreen? m_screen;

		public int m_selectedSlotIndex = -1;

		public bool m_selectedSlotIsEmpty;

		public bool IsOpen;

		public Coroutine? m_openRoutine;

		public Coroutine? m_closeRoutine;

		public Queue<ArchiveMenuEntry?> m_newEntries = new Queue<ArchiveMenuEntry>();

		public int m_numFilledEntries;

		public SaveSlotButton m_templateSlotButton;

		public bool m_isClosing;

		public void OnDestroy()
		{
			if (m_screen != null)
			{
				m_screen.Dispose();
				m_screen = null;
			}
			if (m_openRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(m_openRoutine);
				m_openRoutine = null;
			}
			if (m_closeRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(m_closeRoutine);
				m_closeRoutine = null;
			}
			if (IsOpen || m_isClosing)
			{
				IsOpen = false;
				m_isClosing = false;
				UIManager instance = UIManager.instance;
				((MonoBehaviour)instance).StartCoroutine(instance.GoToProfileMenu());
			}
		}

		public void OpenForSlot(SaveSlotButton slot)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			if (!IsOpen)
			{
				if (m_closeRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(m_closeRoutine);
					m_closeRoutine = null;
				}
				m_selectedSlotIndex = slot.SaveSlotIndex;
				m_selectedSlotIsEmpty = (int)slot.saveFileState == 2;
				m_templateSlotButton = slot;
				IsOpen = true;
				m_isClosing = false;
				m_openRoutine = ((MonoBehaviour)this).StartCoroutine(OpenRoutine());
			}
		}

		public void Close()
		{
			if (IsOpen && !m_isClosing)
			{
				m_isClosing = true;
				if (m_openRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(m_openRoutine);
					m_openRoutine = null;
				}
				m_closeRoutine = ((MonoBehaviour)this).StartCoroutine(CloseRoutine());
			}
		}

		public void Update()
		{
			if (IsOpen)
			{
				InputHandler inputHandler = GameManager.instance.inputHandler;
				if (inputHandler.acceptingInput && ((OneAxisInputControl)inputHandler.inputActions.MenuCancel).WasPressed)
				{
					((OneAxisInputControl)inputHandler.inputActions.MenuCancel).ClearInputState();
					UIManager.instance.uiAudioPlayer.PlayCancel();
					Close();
				}
			}
		}

		public IEnumerator OpenRoutine()
		{
			GameManager.instance.inputHandler.StopUIInput();
			m_screen?.Dispose();
			string title = (m_selectedSlotIsEmpty ? Strings.TitleLoadIntoEmpty : Strings.TitleArchiveSwap);
			string name;
			string slotInfo = (SaveName.TryGetSlotName(m_selectedSlotIndex, out name) ? Strings.NamedSlotInfo(name, m_selectedSlotIndex) : Strings.UnnamedSlotInfo(m_selectedSlotIndex));
			string statusMessage = slotInfo + "\n" + Strings.LoadingText;
			m_screen = new ArchiveMenuScreen(title, statusMessage, (Action)Close, out var statusText);
			m_newEntries.Clear();
			m_numFilledEntries = 0;
			for (int i = 1; i <= 4; i++)
			{
				AddEntry(i);
			}
			yield return (object)new WaitUntil((Func<bool>)(() => m_newEntries.Count == 4));
			for (int num = 1; num <= 4; num++)
			{
				ArchiveMenuEntry archiveMenuEntry = m_newEntries.Dequeue();
				if (archiveMenuEntry != null)
				{
					m_screen.Add(archiveMenuEntry);
				}
			}
			UIManager instance = UIManager.instance;
			if ((int)instance.menuState == 6)
			{
				yield return ((MonoBehaviour)this).StartCoroutine(instance.HideSaveProfileMenu(true));
			}
			yield return ((MonoBehaviour)this).StartCoroutine(m_screen.Show());
			for (int i2 = 5; i2 <= 50; i2++)
			{
				AddEntry(i2);
				yield return (object)new WaitUntil((Func<bool>)(() => m_newEntries.Count > 0));
				ArchiveMenuEntry archiveMenuEntry2 = m_newEntries.Dequeue();
				if (archiveMenuEntry2 != null)
				{
					m_screen.Add(archiveMenuEntry2);
				}
				yield return (object)new WaitForSeconds(0.01f);
			}
			if (m_numFilledEntries == 0)
			{
				statusText.text = slotInfo + "\n" + Strings.NoLoadableSavesFound;
			}
			else
			{
				statusText.text = slotInfo ?? "";
			}
			m_openRoutine = null;
		}

		public void AddEntry(int slotIndex)
		{
			if (slotIndex == m_selectedSlotIndex)
			{
				m_newEntries.Enqueue(null);
				return;
			}
			GameManager.instance.GetSaveStatsForSlot(slotIndex, (Action<SaveStats, string>)delegate(SaveStats stats, string message)
			{
				OnSaveStatsReceived(slotIndex, stats, message);
			});
		}

		public void OnSaveStatsReceived(int slotIndex, SaveStats? stats, string? message)
		{
			bool isEmpty = stats == null && message == null;
			if (isEmpty && m_selectedSlotIsEmpty)
			{
				m_newEntries.Enqueue(null);
				return;
			}
			ArchiveMenuEntry item = new ArchiveMenuEntry(slotIndex, stats, message, m_templateSlotButton)
			{
				OnSubmit = delegate
				{
					if (m_selectedSlotIsEmpty)
					{
						SaveArchive.LoadSlot(m_selectedSlotIndex, slotIndex);
					}
					else if (isEmpty)
					{
						SaveArchive.ArchiveSlot(m_selectedSlotIndex, slotIndex);
					}
					else
					{
						SaveArchive.SwapSlots(m_selectedSlotIndex, slotIndex);
					}
					Close();
					UIManager.instance.ReloadSaves();
				}
			};
			m_newEntries.Enqueue(item);
			m_numFilledEntries++;
		}

		public IEnumerator CloseRoutine()
		{
			GameManager.instance.inputHandler.StopUIInput();
			UIManager ui = UIManager.instance;
			if (m_screen != null)
			{
				yield return ((MonoBehaviour)this).StartCoroutine(m_screen.Hide());
				m_screen.Dispose();
				m_screen = null;
			}
			IsOpen = false;
			yield return ((MonoBehaviour)this).StartCoroutine(ui.GoToProfileMenu());
			m_isClosing = false;
			m_closeRoutine = null;
		}
	}
	public class RenameEditor : IDisposable
	{
		public SaveSlotButton m_saveSlotButton;

		public InputHandler m_inputHandler;

		public InputField m_renameInput;

		public Animator m_leftCursor;

		public Animator m_rightCursor;

		public bool IsOpen;

		private Action m_onCloseCallback;

		public RenameEditor(SaveSlotButton button, Action onCloseCallback, Action<string> onValueChangedCallback)
		{
			RenameEditor renameEditor = this;
			m_saveSlotButton = button;
			m_inputHandler = GameManager.instance.inputHandler;
			m_onCloseCallback = onCloseCallback;
			m_renameInput = BuildTextInput(m_saveSlotButton, out m_leftCursor, out m_rightCursor);
			((UnityEvent<string>)(object)m_renameInput.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				onValueChangedCallback(value);
			});
			((UnityEvent<string>)(object)m_renameInput.onSubmit).AddListener((UnityAction<string>)delegate
			{
				renameEditor.Close(saveChanges: true);
			});
			((UnityEvent<string>)(object)m_renameInput.onEndEdit).AddListener((UnityAction<string>)delegate
			{
				renameEditor.Close(saveChanges: false);
			});
		}

		public void Dispose()
		{
			Object.Destroy((Object)(object)((Component)m_renameInput).gameObject);
		}

		public void Open()
		{
			if (!IsOpen)
			{
				if (SaveName.TryGetSlotName(m_saveSlotButton.SaveSlotIndex, out string name))
				{
					m_renameInput.text = name;
				}
				else
				{
					m_renameInput.text = string.Empty;
				}
				IsOpen = true;
				UIManager instance = UIManager.instance;
				instance.inputModule.focusOnMouseHover = false;
				((MonoBehaviour)instance).StartCoroutine(FadeInAndSelect());
				m_leftCursor.ResetTrigger(MenuSelectable._hidePropId);
				m_leftCursor.SetTrigger(MenuSelectable._showPropId);
				m_rightCursor.ResetTrigger(MenuSelectable._hidePropId);
				m_rightCursor.SetTrigger(MenuSelectable._showPropId);
			}
		}

		public void Close(bool saveChanges)
		{
			if (IsOpen)
			{
				UIManager instance = UIManager.instance;
				if (saveChanges)
				{
					instance.uiAudioPlayer.PlaySubmit();
					SaveName.SetSlotName(m_saveSlotButton.SaveSlotIndex, m_renameInput.text);
				}
				else
				{
					instance.uiAudioPlayer.PlayCancel();
				}
				((MonoBehaviour)instance).StartCoroutine(FadeOut());
				m_leftCursor.ResetTrigger(MenuSelectable._showPropId);
				m_leftCursor.SetTrigger(MenuSelectable._hidePropId);
				m_rightCursor.ResetTrigger(MenuSelectable._showPropId);
				m_rightCursor.SetTrigger(MenuSelectable._hidePropId);
				IsOpen = false;
				instance.inputModule.focusOnMouseHover = true;
				m_onCloseCallback?.Invoke();
			}
		}

		public IEnumerator FadeInAndSelect()
		{
			((Component)m_renameInput).gameObject.SetActive(true);
			Color baseColor = ((Graphic)m_renameInput.textComponent).color;
			Text textComponent = m_renameInput.textComponent;
			Color color = baseColor;
			color.a = 0f;
			((Graphic)textComponent).color = color;
			float alpha = 0f;
			while (alpha < 1f)
			{
				alpha += Time.unscaledDeltaTime * UIManager.instance.MENU_FADE_SPEED;
				Text textComponent2 = m_renameInput.textComponent;
				color = baseColor;
				color.a = alpha;
				((Graphic)textComponent2).color = color;
				yield return null;
			}
			Text textComponent3 = m_renameInput.textComponent;
			color = baseColor;
			color.a = 1f;
			((Graphic)textComponent3).color = color;
			EventSystem current = EventSystem.current;
			if (current != null)
			{
				current.SetSelectedGameObject(((Component)m_renameInput).gameObject);
			}
			m_renameInput.ActivateInputField();
		}

		public IEnumerator FadeOut()
		{
			Color baseColor = ((Graphic)m_renameInput.textComponent).color;
			float alpha = 1f;
			Color color;
			while (alpha > 0f)
			{
				alpha -= Time.unscaledDeltaTime * UIManager.instance.MENU_FADE_SPEED;
				Text textComponent = m_renameInput.textComponent;
				color = baseColor;
				color.a = alpha;
				((Graphic)textComponent).color = color;
				yield return null;
			}
			Text textComponent2 = m_renameInput.textComponent;
			color = baseColor;
			color.a = 0f;
			((Graphic)textComponent2).color = color;
			((Component)m_renameInput).gameObject.SetActive(false);
		}

		public static InputField BuildTextInput(SaveSlotButton saveSlotButton, out Animator leftCursor, out Animator rightCursor)
		{
			//IL_0107: 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_015d: 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_0178: 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_0188: 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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)saveSlotButton).GetComponent<RectTransform>();
			RectTransform component2 = ((Component)saveSlotButton.clearSaveButton).GetComponent<RectTransform>();
			GameObject obj = Object.Instantiate<GameObject>(SfmUtil.GetChild(SfmUtil.GetChild(((Component)UIManager.instance).gameObject, "UICanvas"), "GameOptionsMenuScreen/Content/CamShakeSetting/CamShakePopupOption"), ((Transform)component2).parent, false);
			obj.SetActive(false);
			((Object)obj).name = "SFM-RenameEditor";
			SfmUtil.RemoveComponent<MenuSetting>(obj);
			Object.Destroy((Object)(object)SfmUtil.GetChild(obj, "Menu Option Label"));
			Object.Destroy((Object)(object)SfmUtil.GetChild(obj, "Description"));
			MenuOptionHorizontal component3 = obj.GetComponent<MenuOptionHorizontal>();
			leftCursor = ((MenuSelectable)component3).leftCursor;
			rightCursor = ((MenuSelectable)component3).rightCursor;
			Object.DestroyImmediate((Object)(object)component3);
			Text childComponent = SfmUtil.GetChildComponent<Text>(obj, "Menu Option Text");
			((Object)((Component)childComponent).gameObject).name = "SFM-RenameEditorText";
			SfmUtil.RemoveComponent<ChangeTextFontScaleOnHandHeld>(((Component)childComponent).gameObject);
			SfmUtil.RemoveComponent<FixVerticalAlign>(((Component)childComponent).gameObject);
			childComponent.fontSize = saveSlotButton.locationText.fontSize;
			childComponent.horizontalOverflow = (HorizontalWrapMode)0;
			childComponent.verticalOverflow = (VerticalWrapMode)1;
			childComponent.alignment = (TextAnchor)5;
			childComponent.lineSpacing = 1f;
			InputField val = obj.AddComponent<InputField>();
			val.textComponent = childComponent;
			val.caretColor = Color.white;
			val.contentType = (ContentType)0;
			val.lineType = (LineType)1;
			val.caretWidth = 8;
			val.text = "";
			val.characterLimit = 32;
			RectTransform component4 = obj.GetComponent<RectTransform>();
			component4.anchorMin = component2.anchorMin;
			component4.anchorMax = component2.anchorMax;
			component4.pivot = component2.pivot;
			component4.anchoredPosition = new Vector2(0f, component2.anchoredPosition.y);
			Rect rect = component.rect;
			float width = ((Rect)(ref rect)).width;
			rect = component2.rect;
			component4.sizeDelta = new Vector2(width, ((Rect)(ref rect)).height);
			RectTransform component5 = ((Component)childComponent).gameObject.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 0f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.anchoredPosition = new Vector2(0f, 0f);
			component5.sizeDelta = new Vector2(0f, 0f);
			return val;
		}
	}
	public class SaveOptions : MonoBehaviour
	{
		public SaveSlotButton m_saveSlotButton;

		public SaveSlotActionRow m_actionRow;

		public ArchiveSlotSelectionMenu m_archiveMenu;

		public RenameEditor m_renameEditor;

		public Text m_nameLabel;

		public Text m_defeatedNameLabel;

		public void Initialize(SaveSlotButton button)
		{
			m_saveSlotButton = button;
			m_archiveMenu = SaveFileManagerPlugin.s_instance.m_archiveMenu;
			SfmLogger.LogInfo("Creating SaveOptions for " + ((Object)button).name);
			m_actionRow = new SaveSlotActionRow(m_saveSlotButton, OpenRenameEditor, OpenArchiveMenu);
			m_renameEditor = new RenameEditor(m_saveSlotButton, OnRenameEditorClosed, delegate(string value)
			{
				m_nameLabel.text = value;
				m_defeatedNameLabel.text = value;
			});
			CreateNameLabels();
		}

		public void OnDestroy()
		{
			SfmLogger.LogInfo("Destroying SaveOptions for " + ((Object)m_saveSlotButton).name);
			m_actionRow.Dispose();
			m_renameEditor.Dispose();
			Object.Destroy((Object)(object)((Component)m_nameLabel).gameObject);
			Object.Destroy((Object)(object)((Component)m_defeatedNameLabel).gameObject);
		}

		public void SetupNavigation(SaveOptions? previousOptions, SaveOptions? nextOptions)
		{
			m_actionRow.SetupNavigation(previousOptions?.m_actionRow, nextOptions?.m_actionRow);
		}

		public void Update()
		{
			SyncFromSlotState();
		}

		public void SyncFromSlotState()
		{
			if (!m_renameEditor.IsOpen)
			{
				m_actionRow.Refresh();
				string name;
				bool active = SaveName.TryGetSlotName(m_saveSlotButton.SaveSlotIndex, out name);
				m_nameLabel.text = name;
				((Component)m_nameLabel).gameObject.SetActive(active);
				m_defeatedNameLabel.text = name;
				((Component)m_defeatedNameLabel).gameObject.SetActive(active);
			}
		}

		public void OpenRenameEditor()
		{
			if (!m_renameEditor.IsOpen && !m_archiveMenu.IsOpen)
			{
				m_actionRow.SetButtonVisibility(visible: false);
				m_renameEditor.Open();
			}
		}

		public void OnRenameEditorClosed()
		{
			m_actionRow.SetButtonVisibility(visible: true, m_actionRow.m_rename);
			SyncFromSlotState();
		}

		public void OpenArchiveMenu()
		{
			if (!m_renameEditor.IsOpen && !m_archiveMenu.IsOpen)
			{
				m_archiveMenu.OpenForSlot(m_saveSlotButton);
			}
		}

		public void CreateNameLabels()
		{
			//IL_0079: 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)
			//IL_0105: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			m_nameLabel = Object.Instantiate<Text>(m_saveSlotButton.locationText, ((Component)m_saveSlotButton.locationText).transform.parent);
			((Object)m_nameLabel).name = "SFM-SaveNameLabel";
			m_nameLabel.fontSize = Mathf.Max(16, m_saveSlotButton.locationText.fontSize - 6);
			((Graphic)m_nameLabel).color = new Color(1f, 0.86f, 0.58f, 1f);
			((Graphic)m_nameLabel).raycastTarget = false;
			((Component)m_nameLabel).gameObject.SetActive(false);
			m_defeatedNameLabel = Object.Instantiate<Text>(m_nameLabel, ((Component)m_saveSlotButton.defeatedBackground).transform);
			((Object)m_defeatedNameLabel).name = "SFM-SaveNameLabel-Defeated";
			((Graphic)m_defeatedNameLabel).rectTransform.anchorMin = new Vector2(1f, 0f);
			((Graphic)m_defeatedNameLabel).rectTransform.anchorMax = new Vector2(1f, 0f);
			((Graphic)m_defeatedNameLabel).rectTransform.anchoredPosition = new Vector2(-30f, 53f);
			((Graphic)m_defeatedNameLabel).rectTransform.pivot = new Vector2(1f, 0f);
			m_defeatedNameLabel.alignment = (TextAnchor)8;
		}
	}
	public class SaveSlotActionButton : MenuButton, ISubmitHandler, IEventSystemHandler, IPointerClickHandler, ISelectHandler
	{
		public Animator? selectIcon;

		public Image? m_iconImage;

		public Sprite? m_iconIdle;

		public Sprite? m_iconTransition;

		public Sprite? m_iconSelected;

		public Action? onSubmit;

		public static readonly int _isSelectedProp = Animator.StringToHash("Is Selected");

		public void Initialize(string assetName, Action onSubmit)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			this.onSubmit = onSubmit;
			base.buttonType = (MenuButtonType)1;
			SfmUtil.RemoveComponent<ZeroAlphaOnStart>(((Component)this).gameObject);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			m_iconIdle = LoadTexture(executingAssembly, "SaveFileManagerMod.assets.finished." + assetName + "_01_idle.png");
			m_iconTransition = LoadTexture(executingAssembly, "SaveFileManagerMod.assets.finished." + assetName + "_02_transition.png");
			m_iconSelected = LoadTexture(executingAssembly, "SaveFileManagerMod.assets.finished." + assetName + "_03_selected.png");
			Transform val = ((Component)this).transform.Find("Trash Icon");
			((Object)val).name = "SFM-" + assetName + "Icon";
			m_iconImage = ((Component)val).gameObject.GetComponent<Image>();
			m_iconImage.overrideSprite = m_iconIdle;
		}

		public override void OnMove(AxisEventData eventData)
		{
			if (!TryNavigateSkippingDisabled(eventData, (Selectable)(object)this))
			{
				((Selectable)this).OnMove(eventData);
			}
		}

		public void Navigate(AxisEventData eventData, Selectable sel)
		{
			if (((UIBehaviour)sel).IsActive() && sel.IsInteractable())
			{
				((BaseEventData)eventData).selectedObject = ((Component)sel).gameObject;
			}
			else
			{
				TryNavigateSkippingDisabled(eventData, sel);
			}
		}

		public void OnSubmit(BaseEventData eventData)
		{
			if (((Selectable)this).interactable)
			{
				((MenuButton)this).OnSubmit(eventData);
				((MenuSelectable)this).ForceDeselect();
				onSubmit?.Invoke();
			}
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			OnSubmit((BaseEventData)(object)eventData);
		}

		public void OnSelect(BaseEventData eventData)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			((MenuSelectable)this).OnSelect(eventData);
			if (((Component)this).GetComponent<CanvasGroup>().interactable)
			{
				Animator? obj = selectIcon;
				if (obj != null)
				{
					obj.SetBool(_isSelectedProp, true);
				}
				((MonoBehaviour)this).StartCoroutine(SelectAnimation());
			}
			else
			{
				Navigation navigation = ((Selectable)this).navigation;
				((MonoBehaviour)this).StartCoroutine(SelectAfterFrame(((Component)((Navigation)(ref navigation)).selectOnUp).gameObject));
			}
		}

		public override void OnDeselected(BaseEventData eventData)
		{
			Animator? obj = selectIcon;
			if (obj != null)
			{
				obj.SetBool(_isSelectedProp, false);
			}
			((MonoBehaviour)this).StartCoroutine(DeselectAnimation());
		}

		public IEnumerator SelectAfterFrame(GameObject obj)
		{
			yield return (object)new WaitForEndOfFrame();
			EventSystem.current.SetSelectedGameObject(obj);
		}

		public IEnumerator SelectAnimation()
		{
			yield return (object)new WaitForSeconds(0.06f);
			m_iconImage.overrideSprite = m_iconTransition;
			yield return (object)new WaitForSeconds(0.06f);
			m_iconImage.overrideSprite = m_iconSelected;
		}

		public IEnumerator DeselectAnimation()
		{
			yield return (object)new WaitForSeconds(0.06f);
			m_iconImage.overrideSprite = m_iconTransition;
			yield return (object)new WaitForSeconds(0.06f);
			m_iconImage.overrideSprite = m_iconIdle;
		}

		public static bool TryNavigateSkippingDisabled(AxisEventData eventData, Selectable start)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000a: 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_001c: Invalid comparison between Unknown and I4
			if ((int)eventData.moveDir != 2 && (int)eventData.moveDir != 0)
			{
				return false;
			}
			Selectable val = start;
			do
			{
				Selectable val2 = (((int)eventData.moveDir == 2) ? val.FindSelectableOnRight() : val.FindSelectableOnLeft());
				if ((Object)(object)val2 == (Object)null)
				{
					return false;
				}
				val = val2;
			}
			while (!((UIBehaviour)val).IsActive() || !val.IsInteractable());
			((BaseEventData)eventData).selectedObject = ((Component)val).gameObject;
			return true;
		}

		public static Sprite? LoadTexture(Assembly assembly, string resourceName)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = assembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				SfmLogger.LogError("Failed to find embedded resource: " + resourceName);
				return null;
			}
			byte[] array = new byte[stream.Length];
			if (stream.Read(array, 0, array.Length) != array.Length)
			{
				SfmLogger.LogError("Failed to read the entire resource: " + resourceName);
				return null;
			}
			Texture2D val = new Texture2D(100, 100, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				SfmLogger.LogError("Failed to load image from resource: " + resourceName);
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 70f);
		}
	}
	public class SaveSlotActionRow : IDisposable
	{
		public readonly SaveSlotButton m_slot;

		public readonly Navigation m_originalRestoreNav;

		public readonly Navigation m_originalClearNav;

		public readonly ActionButtonWrapper m_restore;

		public readonly ActionButtonWrapper m_rename;

		public readonly ActionButtonWrapper m_archive;

		public readonly ActionButtonWrapper m_clear;

		public readonly List<ActionButtonWrapper> m_buttons;

		public bool m_disposed;

		public SaveSlotActionRow(SaveSlotButton slot, Action onRename, Action onArchive)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			m_slot = slot;
			RestoreSaveButton restoreSaveButton = m_slot.restoreSaveButton;
			m_originalRestoreNav = ((Selectable)restoreSaveButton).navigation;
			ClearSaveButton val = ((Component)m_slot.clearSaveButton).GetComponent<ClearSaveButton>() ?? throw new Exception("Could not find clear save button component");
			m_originalClearNav = ((Selectable)val).navigation;
			m_restore = new ActionButtonWrapper((MenuButton)(object)restoreSaveButton, isOriginal: true);
			m_rename = new ActionButtonWrapper((MenuButton)(object)CloneIconButton("Rename", onRename), isOriginal: false);
			m_archive = new ActionButtonWrapper((MenuButton)(object)CloneIconButton("Archive", onArchive), isOriginal: false);
			m_clear = new ActionButtonWrapper((MenuButton)(object)val, isOriginal: true);
			m_buttons = new List<ActionButtonWrapper>(4) { m_restore, m_rename, m_archive, m_clear };
		}

		public void Dispose()
		{
			//IL_0046: 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)
			if (!m_disposed)
			{
				m_disposed = true;
				Object.Destroy((Object)(object)((Component)m_rename.button).gameObject);
				Object.Destroy((Object)(object)((Component)m_archive.button).gameObject);
				((Selectable)m_restore.button).navigation = m_originalRestoreNav;
				Extensions.SetLocalPositionX(((Component)m_restore.button).transform, -67f);
				((Selectable)m_clear.button).navigation = m_originalClearNav;
				Extensions.SetLocalPositionX(((Component)m_clear.button).transform, 67f);
			}
		}

		public void Refresh()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			if (!m_disposed)
			{
				bool flag = false;
				bool flag2 = false;
				bool flag3 = false;
				SlotState state = m_slot.State;
				switch ((int)state)
				{
				case 0:
				case 1:
				case 10:
					flag = true;
					break;
				case 2:
				case 9:
					flag2 = true;
					break;
				case 4:
					flag3 = true;
					break;
				}
				m_restore.SetUsable(!flag && !flag2 && !flag3);
				m_rename.SetUsable(!flag && !flag2);
				m_archive.SetUsable(!flag);
				m_clear.SetUsable(!flag && !flag2);
				UpdateLayout();
			}
		}

		public void SetButtonVisibility(bool visible, ActionButtonWrapper? focusedElement = null)
		{
			foreach (ActionButtonWrapper button in m_buttons)
			{
				button.SetVisibility(visible, button == focusedElement);
			}
		}

		public SaveSlotActionButton CloneIconButton(string name, Action onSubmit)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_006b: 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_007a: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00d8: 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)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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)
			//IL_0135: 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)
			GameObject gameObject = ((Component)m_slot.clearSaveButton).gameObject;
			GameObject val = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
			((Object)val).name = "SFM-" + name + "Button";
			ClearSaveButton obj = val.GetComponent<ClearSaveButton>() ?? throw new Exception("Could not find MenuButton on " + ((Object)val).name);
			Navigation navigation = ((Selectable)obj).navigation;
			bool interactable = ((Selectable)obj).interactable;
			Transition transition = ((Selectable)obj).transition;
			Graphic targetGraphic = ((Selectable)obj).targetGraphic;
			ColorBlock colors = ((Selectable)obj).colors;
			SpriteState spriteState = ((Selectable)obj).spriteState;
			CancelAction cancelAction = ((MenuSelectable)obj).cancelAction;
			bool playSubmitSound = ((MenuSelectable)obj).playSubmitSound;
			VibrationDataAsset menuSubmitVibration = ((MenuSelectable)obj).menuSubmitVibration;
			VibrationDataAsset menuCancelVibration = ((MenuSelectable)obj).menuCancelVibration;
			Animator leftCursor = ((MenuSelectable)obj).leftCursor;
			Animator rightCursor = ((MenuSelectable)obj).rightCursor;
			MenuButtonType buttonType = ((MenuButton)obj).buttonType;
			Animator flashEffect = ((MenuButton)obj).flashEffect;
			Animator selectIcon = obj.selectIcon;
			Object.DestroyImmediate((Object)(object)obj);
			SaveSlotActionButton saveSlotActionButton = val.AddComponent<SaveSlotActionButton>();
			((Selectable)saveSlotActionButton).navigation = navigation;
			((Selectable)saveSlotActionButton).interactable = interactable;
			((Selectable)saveSlotActionButton).transition = transition;
			((Selectable)saveSlotActionButton).targetGraphic = targetGraphic;
			((Selectable)saveSlotActionButton).colors = colors;
			((Selectable)saveSlotActionButton).spriteState = spriteState;
			((MenuSelectable)saveSlotActionButton).cancelAction = cancelAction;
			((MenuSelectable)saveSlotActionButton).playSubmitSound = playSubmitSound;
			((MenuSelectable)saveSlotActionButton).menuSubmitVibration = menuSubmitVibration;
			((MenuSelectable)saveSlotActionButton).menuCancelVibration = menuCancelVibration;
			((MenuSelectable)saveSlotActionButton).leftCursor = leftCursor;
			((MenuSelectable)saveSlotActionButton).rightCursor = rightCursor;
			((MenuButton)saveSlotActionButton).buttonType = buttonType;
			((MenuButton)saveSlotActionButton).flashEffect = flashEffect;
			saveSlotActionButton.selectIcon = selectIcon;
			saveSlotActionButton.Initialize(name, onSubmit);
			return saveSlotActionButton;
		}

		public void UpdateLayout()
		{
			List<RectTransform> list = (from b in m_buttons
				where b.canUse
				select b.rectTransform).ToList();
			float num = 134f;
			float num2 = (0f - (float)(list.Count - 1) * num) / 2f;
			foreach (RectTransform item in list)
			{
				Extensions.SetLocalPositionX((Transform)(object)item, num2);
				num2 += num;
			}
		}

		public void SetupNavigation(SaveSlotActionRow? previousRow, SaveSlotActionRow? nextRow)
		{
			//IL_0018: 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_00eb: 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_0103: 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_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)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < m_buttons.Count; i++)
			{
				Navigation navigation = ((Selectable)m_buttons[i].button).navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)m_slot;
				((Navigation)(ref navigation)).selectOnDown = m_slot.backButton;
				((Navigation)(ref navigation)).selectOnLeft = (Selectable)(object)((i > 0) ? m_buttons[i - 1].button : previousRow?.m_clear.button);
				((Navigation)(ref navigation)).selectOnRight = (Selectable)(object)((i < m_buttons.Count - 1) ? m_buttons[i + 1].button : nextRow?.m_restore.button);
				((Selectable)m_buttons[i].button).navigation = navigation;
			}
			SaveSlotButton slot = m_slot;
			Navigation val = m_slot.emptySlotNav;
			((Navigation)(ref val)).selectOnDown = (Selectable)(object)m_archive.button;
			slot.emptySlotNav = val;
			SaveSlotButton slot2 = m_slot;
			val = m_slot.defeatedSlotNav;
			((Navigation)(ref val)).selectOnDown = (Selectable)(object)m_archive.button;
			slot2.defeatedSlotNav = val;
		}
	}
	public static class SfmUtil
	{
		public static GameObject? GetChild(GameObject parent, string childPath)
		{
			Transform val = parent.transform.Find(childPath);
			if ((Object)(object)val == (Object)null)
			{
				SfmLogger.LogError("Could not find child '" + childPath + "' in '" + ((Object)parent).name + "'");
				return null;
			}
			return ((Component)val).gameObject;
		}

		public static T? GetChildComponent<T>(GameObject parent, string childPath) where T : class
		{
			GameObject child = GetChild(parent, childPath);
			if ((Object)(object)child == (Object)null)
			{
				return null;
			}
			T component = child.GetComponent<T>();
			if (component == null)
			{
				SfmLogger.LogError("Could not find component '" + typeof(T).Name + "' in '" + ((Object)parent).name + "/" + childPath + "'");
				return null;
			}
			return component;
		}

		public static void RemoveComponent<T>(GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
				return;
			}
			SfmLogger.LogWarning("RemoveComponent: Could not find component '" + typeof(T).Name + "' in '" + ((Object)gameObject).name + "'");
		}

		public static void RemoveComponentImmediate<T>(GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
				return;
			}
			SfmLogger.LogWarning("RemoveComponentImmediate: Could not find component '" + typeof(T).Name + "' in '" + ((Object)gameObject).name + "'");
		}
	}
	public class StringHelper
	{
		public static string ModSheet => "Mods.io.github.mich101mich.savefilemanagermod";

		public static string Get(string key, string fallback)
		{
			if (!Language.Has(key, ModSheet))
			{
				return fallback;
			}
			return Language.Get(key, ModSheet);
		}

		public static string Get(string key, string fallback, object args)
		{
			string text = Get(key, fallback);
			PropertyInfo[] properties = args.GetType().GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				text = text.Replace("{" + propertyInfo.Name + "}", propertyInfo.GetValue(args).ToString());
			}
			return text;
		}
	}
}