Decompiled source of The All You Need Save Manager v1.0.4

BepInEx\plugins\TAYNSM\TAYNSM.dll

Decompiled 2 weeks 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.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Serizalization;
using Zorro.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PEAKSaveManager
{
	[BepInPlugin("com.lucasandersen.peakallyouneedsavemanager", "The All You Need Save Manager", "1.0.0")]
	public sealed class SaveManagerPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass188_0
		{
			public PlayerSnapshot snapshot;

			internal bool <WaitForPlayersRoutine>b__0(Player player)
			{
				PhotonView photonView = GetPhotonView((Component)(object)player);
				if ((Object)(object)photonView == (Object)null)
				{
					return false;
				}
				Player owner = photonView.Owner;
				if (snapshot.actorNumber > 0 && owner != null && owner.ActorNumber == snapshot.actorNumber)
				{
					return true;
				}
				if (owner != null)
				{
					return string.Equals(owner.NickName, snapshot.playerName, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
		}

		[CompilerGenerated]
		private sealed class <ApplyPlayerSnapshotRoutine>d__189 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			public SaveManagerPlugin <>4__this;

			public PlayerSnapshot snapshot;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyPlayerSnapshotRoutine>d__189(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Expected O, but got Unknown
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Character character = player.character;
					if ((Object)(object)character == (Object)null)
					{
						return false;
					}
					saveManagerPlugin.ApplyInventory(player, character, snapshot.inventory);
					saveManagerPlugin.ApplyCharacterSnapshot(character, snapshot.character);
					Vector3 val = snapshot.position.ToUnity();
					PhotonView photonView = GetPhotonView((Component)(object)character);
					Player val2 = (((Object)(object)photonView != (Object)null) ? photonView.Owner : null);
					if ((Object)(object)photonView != (Object)null && val2 != null)
					{
						photonView.RPC("WarpPlayerRPC", val2, new object[2] { val, false });
					}
					else
					{
						((Component)character).transform.position = val;
					}
					if ((Object)(object)photonView != (Object)null && photonView.IsMine)
					{
						((Component)character).transform.eulerAngles = snapshot.rotation.ToUnity();
						character.data.lookValues = snapshot.character.lookValues.ToUnity();
						RecalculateLookDirectionsMethod?.Invoke(character, null);
					}
					else if ((Object)(object)photonView == (Object)null)
					{
						((Component)character).transform.eulerAngles = snapshot.rotation.ToUnity();
					}
					ApplyCharacterVelocity(character, snapshot.velocity, snapshot.angularVelocity);
					ApplyEquippedSelection(player, character, snapshot.inventory);
					<>2__current = (object)new WaitForSeconds(0.05f);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnumeratePlayersFromHandler>d__155 : IEnumerable<Player>, IEnumerable, IEnumerator<Player>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Player <>2__current;

			private int <>l__initialThreadId;

			private IEnumerator <>7__wrap1;

			Player IEnumerator<Player>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumeratePlayersFromHandler>d__155(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
					}
					else
					{
						<>1__state = -1;
						Type type = AccessTools.TypeByName("PlayerHandler");
						if (type == null)
						{
							return false;
						}
						MethodInfo methodInfo = AccessTools.Method(type, "GetAllPlayers", (Type[])null, (Type[])null);
						if (methodInfo == null)
						{
							return false;
						}
						object obj;
						try
						{
							obj = methodInfo.Invoke(null, null);
						}
						catch
						{
							return false;
						}
						if (!(obj is IEnumerable enumerable))
						{
							goto IL_00d9;
						}
						<>7__wrap1 = enumerable.GetEnumerator();
						<>1__state = -3;
					}
					while (<>7__wrap1.MoveNext())
					{
						object current = <>7__wrap1.Current;
						Player val = (Player)((current is Player) ? current : null);
						if (val != null)
						{
							<>2__current = val;
							<>1__state = 1;
							return true;
						}
					}
					<>m__Finally1();
					<>7__wrap1 = null;
					goto IL_00d9;
					IL_00d9:
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap1 is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Player> IEnumerable<Player>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <EnumeratePlayersFromHandler>d__155(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Player>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadSaveRoutine>d__185 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveManagerPlugin <>4__this;

			public string fullPath;

			private SaveEnvelope <envelope>5__2;

			private string <targetScene>5__3;

			private int <appliedCount>5__4;

			private List<PlayerSnapshot>.Enumerator <>7__wrap4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadSaveRoutine>d__185(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 4u)
				{
					try
					{
						if (num == -4 || num == 5)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<envelope>5__2 = null;
				<targetScene>5__3 = null;
				<>7__wrap4 = default(List<PlayerSnapshot>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0249: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_030f: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_045f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0314: Unknown result type (might be due to invalid IL or missing references)
				//IL_0316: 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_031a: Unknown result type (might be due to invalid IL or missing references)
				//IL_031c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_017e: 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_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0320: Unknown result type (might be due to invalid IL or missing references)
				//IL_032d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0337: Expected O, but got Unknown
				bool result;
				try
				{
					int num = <>1__state;
					SaveManagerPlugin saveManagerPlugin = <>4__this;
					switch (num)
					{
					default:
						result = false;
						goto end_IL_0000;
					case 0:
						<>1__state = -1;
						if (saveManagerPlugin.isLoading)
						{
							result = false;
						}
						else
						{
							saveManagerPlugin.isLoading = true;
							saveManagerPlugin.SetStatus("Loading save...", Color.cyan, 10f);
							<>1__state = -3;
							if (!TryReadSaveEnvelope(fullPath, out <envelope>5__2, out var reason))
							{
								saveManagerPlugin.SetStatus("Incompatible save: " + reason, Color.yellow, 6f);
								result = false;
								break;
							}
							if (<envelope>5__2.players.Count == 0)
							{
								saveManagerPlugin.SetStatus("Save file has no player snapshots.", Color.yellow, 6f);
								result = false;
								break;
							}
							if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
							{
								saveManagerPlugin.SetStatus("Only host can load shared saves.", Color.yellow, 4f);
								result = false;
								break;
							}
							<targetScene>5__3 = ResolveTargetScene(<envelope>5__2.metadata);
							bool flag = SaveNeedsNonAirportScene(<envelope>5__2.metadata);
							if (string.IsNullOrWhiteSpace(<targetScene>5__3) && flag)
							{
								if (IsInAirportScene())
								{
									saveManagerPlugin.SetStatus("Saved level is unavailable or mismatched for this version.", Color.yellow, 7f);
									result = false;
									break;
								}
								saveManagerPlugin.SetStatus("Saved level mismatch. Loading into current level.", Color.yellow, 5f);
							}
							int num2;
							if (!string.IsNullOrEmpty(<targetScene>5__3))
							{
								Scene activeScene = SceneManager.GetActiveScene();
								num2 = ((!string.Equals(((Scene)(ref activeScene)).name, <targetScene>5__3, StringComparison.OrdinalIgnoreCase)) ? 1 : 0);
							}
							else
							{
								num2 = 0;
							}
							if (<envelope>5__2.metadata.levelSeed != 0)
							{
								SetPendingSeedForLoad(<envelope>5__2.metadata.levelSeed);
								((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)$"Queued seed {PendingSeedForLoad.Value} for next level generation");
							}
							else
							{
								ClearPendingSeedForLoad();
							}
							if (num2 == 0)
							{
								Ascents.currentAscent = <envelope>5__2.metadata.ascent;
								goto IL_0274;
							}
							<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.LoadSceneRoutine(<targetScene>5__3, <envelope>5__2.metadata.ascent));
							<>1__state = 1;
							result = true;
						}
						goto end_IL_0000;
					case 1:
						<>1__state = -3;
						if (!saveManagerPlugin.lastSceneLoadSucceeded)
						{
							saveManagerPlugin.SetStatus("Failed to load scene '" + <targetScene>5__3 + "'.", Color.red, 6f);
							result = false;
							break;
						}
						goto IL_0274;
					case 2:
					{
						<>1__state = -3;
						if (saveManagerPlugin.CountMatchedPlayers(<envelope>5__2.players) <= 0)
						{
							saveManagerPlugin.SetStatus("No matching players were found for this save.", Color.yellow, 6f);
							result = false;
							break;
						}
						if (!MapHandler.Exists)
						{
							goto IL_034d;
						}
						Segment val2 = ClampSegment(<envelope>5__2.metadata.currentSegment);
						MapHandler val3 = Object.FindFirstObjectByType<MapHandler>();
						Segment val4 = (Segment)(((Object)(object)val3 != (Object)null) ? ((int)val3.GetCurrentSegment()) : 0);
						if ((int)val2 == 0 || val2 == val4)
						{
							goto IL_034d;
						}
						MapHandler.JumpToSegment(val2);
						<>2__current = (object)new WaitForSeconds(0.75f);
						<>1__state = 3;
						result = true;
						goto end_IL_0000;
					}
					case 3:
						<>1__state = -3;
						goto IL_034d;
					case 4:
						<>1__state = -3;
						<appliedCount>5__4 = 0;
						<>7__wrap4 = <envelope>5__2.players.GetEnumerator();
						<>1__state = -4;
						goto IL_042e;
					case 5:
						{
							<>1__state = -4;
							<appliedCount>5__4++;
							goto IL_042e;
						}
						IL_042e:
						while (true)
						{
							if (<>7__wrap4.MoveNext())
							{
								PlayerSnapshot current = <>7__wrap4.Current;
								Player val = saveManagerPlugin.FindPlayer(current);
								if ((Object)(object)val == (Object)null)
								{
									((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)$"Could not find player for snapshot '{current.playerName}' (Actor: {current.actorNumber})");
									continue;
								}
								<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.ApplyPlayerSnapshotRoutine(val, current));
								<>1__state = 5;
								result = true;
							}
							else
							{
								<>m__Finally2();
								<>7__wrap4 = default(List<PlayerSnapshot>.Enumerator);
								if (<appliedCount>5__4 <= 0)
								{
									saveManagerPlugin.SetStatus("Load finished but no players were restored.", Color.yellow, 6f);
									result = false;
									break;
								}
								saveManagerPlugin.RestoreRunMetadata(<envelope>5__2.metadata);
								saveManagerPlugin.SetStatus($"Loaded save successfully ({<appliedCount>5__4}/{<envelope>5__2.players.Count} players).", Color.green, 4f);
								<envelope>5__2 = null;
								<targetScene>5__3 = null;
								<>m__Finally1();
								result = false;
							}
							goto end_IL_0000;
						}
						break;
						IL_034d:
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreWorldInteractablesRoutine(<envelope>5__2));
						<>1__state = 4;
						result = true;
						goto end_IL_0000;
						IL_0274:
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(WaitForPlayersRoutine(<envelope>5__2.players, 20f));
						<>1__state = 2;
						result = true;
						goto end_IL_0000;
					}
					<>m__Finally1();
					end_IL_0000:;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				ClearPendingSeedForLoad();
				saveManagerPlugin.isLoading = false;
				saveManagerPlugin.RefreshSaveFileList();
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				((IDisposable)<>7__wrap4).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadSceneRoutine>d__186 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveManagerPlugin <>4__this;

			public int ascent;

			public string sceneName;

			private bool <usedLoadingScreen>5__2;

			private float <timeout>5__3;

			private AsyncOperation <operation>5__4;

			private float <fallbackTimeout>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadSceneRoutine>d__186(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<operation>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Expected O, but got Unknown
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					saveManagerPlugin.lastSceneLoadSucceeded = false;
					Ascents.currentAscent = ascent;
					try
					{
						GameHandler.AddStatus<SceneSwitchingStatus>((GameStatus)new SceneSwitchingStatus());
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("Could not set scene switching status: " + ex.Message));
					}
					<usedLoadingScreen>5__2 = false;
					try
					{
						LoadingScreenHandler instance = RetrievableResourceSingleton<LoadingScreenHandler>.Instance;
						if ((Object)(object)instance != (Object)null)
						{
							instance.Load((LoadingScreenType)1, (Action)null, new IEnumerator[1] { instance.LoadSceneProcess(sceneName, true, true, 0.5f) });
							<usedLoadingScreen>5__2 = true;
						}
					}
					catch (Exception ex2)
					{
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("LoadingScreenHandler load failed, using fallback load: " + ex2.Message));
					}
					if (!<usedLoadingScreen>5__2)
					{
						<operation>5__4 = SceneManager.LoadSceneAsync(sceneName);
						if (<operation>5__4 == null)
						{
							((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)("Could not start fallback scene load for '" + sceneName + "'."));
							return false;
						}
						<fallbackTimeout>5__5 = 45f;
						goto IL_0144;
					}
					goto IL_0165;
				case 1:
					<>1__state = -1;
					goto IL_0144;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_0165:
					<timeout>5__3 = 45f;
					break;
					IL_0144:
					if (!<operation>5__4.isDone && <fallbackTimeout>5__5 > 0f)
					{
						<fallbackTimeout>5__5 -= Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<operation>5__4 = null;
					goto IL_0165;
				}
				if (<timeout>5__3 > 0f)
				{
					Scene activeScene = SceneManager.GetActiveScene();
					bool num2 = string.Equals(((Scene)(ref activeScene)).name, sceneName, StringComparison.OrdinalIgnoreCase);
					bool flag = !<usedLoadingScreen>5__2 || !LoadingScreenHandler.loading;
					if (num2 && flag)
					{
						saveManagerPlugin.lastSceneLoadSucceeded = true;
						return false;
					}
					<timeout>5__3 -= Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("Timed out waiting for scene '" + sceneName + "' to finish loading."));
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RestoreWorldInteractablesRoutine>d__208 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveEnvelope envelope;

			public SaveManagerPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreWorldInteractablesRoutine>d__208(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Expected O, but got Unknown
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Expected O, but got Unknown
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (envelope == null)
					{
						return false;
					}
					saveManagerPlugin.RestoreCampfires(envelope.campfires);
					saveManagerPlugin.RestoreContainerStates(envelope.containerStates, envelope.luggageStates);
					saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					saveManagerPlugin.RestoreCampfires(envelope.campfires);
					saveManagerPlugin.RestoreContainerStates(envelope.containerStates, envelope.luggageStates);
					saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					<>2__current = (object)new WaitForSeconds(1.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					saveManagerPlugin.RestoreContainerStates(envelope.containerStates, envelope.luggageStates);
					saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					saveManagerPlugin.RestoreGroundItems(envelope.groundItems);
					saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitForPlayersRoutine>d__188 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public float timeoutSeconds;

			public List<PlayerSnapshot> players;

			private float <timeout>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForPlayersRoutine>d__188(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeout>5__2 = Mathf.Max(1f, timeoutSeconds);
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<timeout>5__2 > 0f)
				{
					Player[] array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
					if (array.Length != 0)
					{
						int num = 0;
						for (int i = 0; i < players.Count; i++)
						{
							if (array.Any(new <>c__DisplayClass188_0
							{
								snapshot = players[i]
							}.<WaitForPlayersRoutine>b__0))
							{
								num++;
							}
						}
						if (num > 0)
						{
							return false;
						}
					}
					<timeout>5__2 -= Time.deltaTime;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "com.lucasandersen.peakallyouneedsavemanager";

		public const string PluginName = "The All You Need Save Manager";

		public const string PluginVersion = "1.0.0";

		private const string SaveFilePattern = "*.json";

		private const int UiWindowId = 129193;

		private const string PauseMenuButtonObjectName = "PeakSaveManagerButton";

		private const float PendingSeedLifetimeSeconds = 90f;

		private static readonly MethodInfo RecalculateLookDirectionsMethod = AccessTools.Method(typeof(Character), "RecalculateLookDirections", (Type[])null, (Type[])null);

		private static readonly MethodInfo CampfireUpdateLitMethod = AccessTools.Method(typeof(Campfire), "UpdateLit", (Type[])null, (Type[])null);

		private static readonly MethodInfo CampfireHideLogsMethod = AccessTools.Method(typeof(Campfire), "HideLogs", (Type[])null, (Type[])null);

		private static readonly FieldInfo LuggageStateField = AccessTools.Field(typeof(Luggage), "state");

		private static readonly MethodInfo LuggageOpenRpcMethod = AccessTools.Method(typeof(Luggage), "OpenLuggageRPC", (Type[])null, (Type[])null);

		private static readonly MethodInfo MenuWindowOpenMethod = AccessTools.Method(typeof(MenuWindow), "Open", (Type[])null, (Type[])null);

		private static readonly MethodInfo MenuWindowCloseMethod = AccessTools.Method(typeof(MenuWindow), "Close", (Type[])null, (Type[])null);

		private static readonly MethodInfo RespawnChestSetSpentMethod = AccessTools.PropertySetter(typeof(RespawnChest), "IsSpent");

		private static readonly MethodInfo RespawnChestSetRevivedPlayersMethod = AccessTools.PropertySetter(typeof(RespawnChest), "HasRevivedPlayers");

		private static readonly MethodInfo RespawnChestGetRevivedPlayersMethod = AccessTools.PropertyGetter(typeof(RespawnChest), "HasRevivedPlayers");

		private static readonly FieldInfo RespawnChestRevivedPlayersField = AccessTools.Field(typeof(RespawnChest), "hasRevivedPlayers");

		private static readonly MethodInfo RunManagerRpcSyncTimeMethod = AccessTools.Method(typeof(RunManager), "RPC_SyncTime", new Type[2]
		{
			typeof(float),
			typeof(bool)
		}, (Type[])null);

		private static readonly FieldInfo RunManagerTimerActiveField = AccessTools.Field(typeof(RunManager), "timerActive");

		private static readonly PropertyInfo RopeShooterAmmoProperty = AccessTools.Property(typeof(RopeShooter), "Ammo");

		private static readonly MethodInfo RopeShooterSyncRpcMethod = AccessTools.Method(typeof(RopeShooter), "Sync_Rpc", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly FieldInfo ItemTotalUsesField = AccessTools.Field(typeof(Item), "totalUses");

		private static readonly FieldInfo ItemDataField = AccessTools.Field(typeof(Item), "data");

		private static readonly FieldInfo MagicBeanVineCurrentLengthField = AccessTools.Field(typeof(MagicBeanVine), "currentLength");

		private static readonly FieldInfo MagicBeanVineInitialLengthField = AccessTools.Field(typeof(MagicBeanVine), "initialLength");

		private static readonly FieldInfo MagicBeanVineMaxLengthField = AccessTools.Field(typeof(MagicBeanVine), "maxLength");

		private static readonly FieldInfo CloudFungusAlreadyBrokeField = AccessTools.Field(typeof(CloudFungus), "alreadyBroke");

		private static readonly FieldInfo CloudFungusTimeAliveField = AccessTools.Field(typeof(CloudFungus), "timeAlive");

		private static readonly FieldInfo OptionableIntHasDataField = AccessTools.Field(typeof(OptionableIntItemData), "HasData");

		private static readonly FieldInfo OptionableIntValueField = AccessTools.Field(typeof(OptionableIntItemData), "Value");

		private static readonly FieldInfo OptionableBoolHasDataField = AccessTools.Field(typeof(OptionableBoolItemData), "HasData");

		private static readonly FieldInfo OptionableBoolValueField = AccessTools.Field(typeof(OptionableBoolItemData), "Value");

		private static readonly FieldInfo CharacterDataCheckpointFlagsField = AccessTools.Field(typeof(CharacterData), "checkpointFlags");

		private static readonly FieldInfo CheckpointFlagStatusesField = AccessTools.Field(typeof(CheckpointFlag), "currentStatuses");

		private static readonly FieldInfo CheckpointFlagPlanterField = AccessTools.Field(typeof(CheckpointFlag), "planterCharacter");

		private static readonly FieldInfo CharacterItemsCurrentSelectedSlotField = AccessTools.Field(typeof(CharacterItems), "currentSelectedSlot");

		private static readonly MethodInfo CharacterItemsEquipSlotMethod = AccessTools.Method(typeof(CharacterItems), "EquipSlot", new Type[1] { typeof(Optionable<byte>) }, (Type[])null);

		private static readonly ConstructorInfo OptionableByteConstructor = AccessTools.Constructor(typeof(Optionable<byte>), new Type[2]
		{
			typeof(byte),
			typeof(byte)
		}, false);

		private static readonly FieldInfo OptionableByteHasValueField = AccessTools.Field(typeof(Optionable<byte>), "hasValue");

		private static readonly FieldInfo OptionableByteValueField = AccessTools.Field(typeof(Optionable<byte>), "value");

		private static readonly MethodInfo MirageLuggageSetStateMethod = AccessTools.Method(typeof(MirageLuggage), "setMirageState", new Type[1] { typeof(float) }, (Type[])null);

		private static readonly FieldInfo MirageLuggageRenderersField = AccessTools.Field(typeof(MirageLuggage), "renderers");

		private static readonly MethodInfo DayNightTimeStringGetterMethod = AccessTools.PropertyGetter(typeof(DayNightManager), "timeString");

		private static readonly MethodInfo DayNightTimeStringSetterMethod = AccessTools.PropertySetter(typeof(DayNightManager), "timeString");

		private static readonly FieldInfo DayNightTimeStringField = AccessTools.Field(typeof(DayNightManager), "timeString");

		private static readonly HashSet<STATUSTYPE> SkippedSavedStatuses = new HashSet<STATUSTYPE> { (STATUSTYPE)7 };

		private static SaveManagerPlugin Instance;

		private static int? PendingSeedForLoad;

		private static float PendingSeedSetRealtime;

		private Harmony harmony;

		private ConfigEntry<bool> autoSaveEnabled;

		private ConfigEntry<float> autoSaveIntervalSeconds;

		private string saveDirectory;

		private string preferredSaveDirectory;

		private string fallbackSaveDirectory;

		private bool showUi;

		private bool isLoading;

		private float lastAutoSaveTime;

		private bool lastSceneLoadSucceeded = true;

		private Rect windowRect = new Rect(34f, 34f, 820f, 620f);

		private Vector2 fileScroll = Vector2.zero;

		private string newSaveName = "";

		private readonly List<SaveListEntry> saveEntries = new List<SaveListEntry>();

		private string statusMessage = "";

		private Color statusColor = Color.white;

		private float statusMessageUntil;

		private bool hasConfirmationPending;

		private string confirmationTitle = "";

		private string confirmationMessage = "";

		private Action confirmationAction;

		private bool stylesBuilt;

		private GUIStyle windowStyle;

		private GUIStyle sectionStyle;

		private GUIStyle titleStyle;

		private GUIStyle subtitleStyle;

		private GUIStyle normalLabelStyle;

		private GUIStyle errorLabelStyle;

		private GUIStyle softButtonStyle;

		private GUIStyle dangerButtonStyle;

		private GUIStyle textFieldStyle;

		private GUIStyle cardStyle;

		private GUIStyle cardWarningStyle;

		private Texture2D overlayTexture;

		private Texture2D windowTexture;

		private Texture2D sectionTexture;

		private Texture2D cardTexture;

		private Texture2D warningCardTexture;

		private Texture2D buttonTexture;

		private Texture2D buttonHoverTexture;

		private Texture2D dangerButtonTexture;

		private Texture2D textFieldTexture;

		private SaveManagerPausePage pauseMenuPage;

		private UIPageHandler pauseMenuPageHandler;

		private UIPage pauseMenuMainPage;

		private Button pauseMenuButtonTemplate;

		private bool quitPendingSaveDecision;

		private PauseMenuMainPage quitPendingPage;

		private bool allowVanillaQuitClick;

		private void Awake()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			autoSaveEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoSave", "Enable AutoSave", true, "Automatically create rolling autosaves");
			autoSaveIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("AutoSave", "Interval Seconds", 300f, "Seconds between autosaves");
			preferredSaveDirectory = Path.Combine(Paths.GameRootPath, "PeakSaves");
			fallbackSaveDirectory = Path.Combine(Application.persistentDataPath, "PeakSaves");
			saveDirectory = preferredSaveDirectory;
			EnsureSaveDirectoryReady(showStatus: false);
			harmony = new Harmony("com.lucasandersen.peakallyouneedsavemanager");
			harmony.PatchAll();
			RefreshSaveFileList();
			SetStatus("Save manager ready.", Color.cyan, 2f);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded The All You Need Save Manager 1.0.0 by Lucas Andersen");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to unpatch Harmony cleanly: {arg}");
			}
			DestroyUiResources();
		}

		private void Update()
		{
			if (showUi)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
			if (!showUi && !isLoading && autoSaveEnabled.Value && Time.time - lastAutoSaveTime > Mathf.Max(15f, autoSaveIntervalSeconds.Value))
			{
				if (CanAutoSaveNow())
				{
					TrySaveGame("Autosave");
				}
				lastAutoSaveTime = Time.time;
			}
		}

		private bool CanAutoSaveNow()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSaveNow(showReason: false))
			{
				return false;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (string.IsNullOrWhiteSpace(name) || !name.StartsWith("Level_", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (LoadingScreenHandler.loading)
			{
				return false;
			}
			return true;
		}

		private void OnGUI()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (showUi)
			{
				EnsureStyles();
				DrawOverlay();
				GUI.depth = -1000;
				windowRect = GUI.Window(129193, windowRect, new WindowFunction(DrawMainWindow), "PEAK ALL YOU NEED SAVE MANAGER", windowStyle);
			}
		}

		private void DrawMainWindow(int _)
		{
			//IL_0032: 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)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			float num = statusMessageUntil - Time.unscaledTime;
			bool flag = IsInAirportScene();
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			if (!string.IsNullOrEmpty(statusMessage) && num > 0f)
			{
				Color color = GUI.color;
				GUI.color = statusColor;
				GUILayout.Label(statusMessage, sectionStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUI.color = color;
			}
			if (isLoading)
			{
				GUILayout.Label("Loading save and synchronizing players...", sectionStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) });
			}
			if (hasConfirmationPending)
			{
				DrawConfirmationPrompt();
				GUILayout.EndVertical();
				GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 24f));
				return;
			}
			GUILayout.BeginVertical(sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Create Save", subtitleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			if (flag)
			{
				GUILayout.Label("You cannot save in the Airport.", errorLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(4f);
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Name", normalLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			newSaveName = GUILayout.TextField(newSaveName, textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.enabled = !isLoading && !flag;
			if (GUILayout.Button("Quick Save", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(28f),
				GUILayout.Width(120f)
			}))
			{
				TrySaveGame("Quick Save");
			}
			GUI.enabled = !isLoading && !flag && !string.IsNullOrWhiteSpace(newSaveName);
			if (GUILayout.Button("Save", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(28f),
				GUILayout.Width(80f)
			}))
			{
				string saveName = newSaveName.Trim();
				newSaveName = string.Empty;
				TrySaveGame(saveName);
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Saved Runs", subtitleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUI.enabled = !isLoading;
			if (GUILayout.Button("Refresh", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(90f),
				GUILayout.Height(24f)
			}))
			{
				RefreshSaveFileList();
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			fileScroll = GUILayout.BeginScrollView(fileScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(390f) });
			if (saveEntries.Count == 0)
			{
				GUILayout.Label("No save files found.", normalLabelStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (SaveListEntry saveEntry in saveEntries)
				{
					DrawSaveCard(saveEntry);
					GUILayout.Space(5f);
				}
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(120f),
				GUILayout.Height(30f)
			}))
			{
				showUi = false;
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 24f));
		}

		private void DrawSaveCard(SaveListEntry entry)
		{
			GUIStyle obj = (entry.isCompatible ? cardStyle : cardWarningStyle);
			bool flag = CanSaveNow(showReason: false);
			GUILayout.BeginVertical(obj, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(entry.fileName, titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label(FormatBytes(entry.fileSize), normalLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(78f) });
			GUILayout.EndHorizontal();
			if (entry.metadata != null)
			{
				string text = ((entry.metadata.savedAtUtc == default(DateTime)) ? entry.fileTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) : entry.metadata.savedAtUtc.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
				int num = entry.metadata.playerCount;
				if (num <= 0)
				{
					num = 0;
				}
				string text2 = Safe(entry.metadata.levelName);
				if (entry.metadata.levelNumber.HasValue)
				{
					text2 += $" (#{entry.metadata.levelNumber.Value})";
				}
				GUILayout.Label("Saved: " + text, normalLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Level: " + text2 + "   Segment: " + Safe(ToDisplaySegmentName(entry.metadata.currentSegmentName, entry.metadata.biomeId)), normalLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Seed: {entry.metadata.levelSeed}   Ascent: {entry.metadata.ascent}   Players: {num}", normalLabelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label(FormatRunSummary(entry.metadata), normalLabelStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label($"File Time: {entry.fileTime:yyyy-MM-dd HH:mm:ss}", normalLabelStyle, Array.Empty<GUILayoutOption>());
			}
			if (!entry.isCompatible)
			{
				GUILayout.Label("Incompatible: " + entry.incompatibilityReason, errorLabelStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.enabled = !isLoading && entry.isCompatible;
			if (GUILayout.Button("Load", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(24f),
				GUILayout.Width(90f)
			}))
			{
				StartLoadFromUi(entry.fullPath);
			}
			GUI.enabled = !isLoading && flag;
			if (GUILayout.Button("Overwrite", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(24f),
				GUILayout.Width(100f)
			}))
			{
				string saveNameHint = ((entry.metadata != null && !string.IsNullOrWhiteSpace(entry.metadata.saveName)) ? entry.metadata.saveName : Path.GetFileNameWithoutExtension(entry.fileName));
				string targetPath2 = entry.fullPath;
				string fileName = entry.fileName;
				RequestConfirmation("Overwrite Save?", "Overwrite '" + fileName + "' with your current run state?", delegate
				{
					TryOverwriteSave(targetPath2, saveNameHint);
				});
			}
			GUI.enabled = !isLoading;
			if (GUILayout.Button("Delete", dangerButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(24f),
				GUILayout.Width(90f)
			}))
			{
				string targetPath = entry.fullPath;
				string fileName2 = entry.fileName;
				RequestConfirmation("Delete Save?", "Delete '" + fileName2 + "' permanently? This cannot be undone.", delegate
				{
					TryDeleteSave(targetPath);
				});
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		private void StartLoadFromUi(string fullPath)
		{
			if (!string.IsNullOrWhiteSpace(fullPath))
			{
				showUi = false;
				ClearPendingConfirmation();
				pauseMenuPage?.PrepareForLoad();
				ClosePauseMenuForLoad();
				((MonoBehaviour)this).StartCoroutine(LoadSaveRoutine(fullPath));
			}
		}

		private void ClosePauseMenuForLoad()
		{
			try
			{
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				PauseMainMenu val = Object.FindFirstObjectByType<PauseMainMenu>();
				if ((Object)(object)val != (Object)null)
				{
					CloseMenuWindow((MenuWindow)(object)val);
					((Component)val).gameObject.SetActive(false);
				}
				if ((Object)(object)pauseMenuPage != (Object)null)
				{
					((Component)pauseMenuPage).gameObject.SetActive(false);
				}
				if ((Object)(object)pauseMenuPageHandler != (Object)null)
				{
					((Component)pauseMenuPageHandler).gameObject.SetActive(false);
				}
				Cursor.visible = false;
				Cursor.lockState = (CursorLockMode)1;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to close pause menu before load: " + ex.Message));
			}
		}

		private void ToggleUi()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				SetStatus("Only the host can open Save Manager.", Color.yellow, 2.5f);
				return;
			}
			showUi = !showUi;
			if (showUi)
			{
				RefreshSaveFileList();
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
			else
			{
				ClearPendingConfirmation();
			}
		}

		private void RequestConfirmation(string title, string message, Action confirmedAction)
		{
			if (confirmedAction != null)
			{
				hasConfirmationPending = true;
				confirmationTitle = (string.IsNullOrWhiteSpace(title) ? "Are you sure?" : title);
				confirmationMessage = (string.IsNullOrWhiteSpace(message) ? "Please confirm this action." : message);
				confirmationAction = confirmedAction;
			}
		}

		private void ClearPendingConfirmation()
		{
			hasConfirmationPending = false;
			confirmationTitle = string.Empty;
			confirmationMessage = string.Empty;
			confirmationAction = null;
		}

		private void ExecutePendingConfirmation()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Action action = confirmationAction;
			ClearPendingConfirmation();
			if (action == null)
			{
				return;
			}
			try
			{
				action();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Confirmation action failed: {arg}");
				SetStatus("Action failed. Check BepInEx log.", Color.red, 4f);
			}
		}

		private void DrawConfirmationPrompt()
		{
			GUILayout.Space(8f);
			GUILayout.BeginVertical(sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(confirmationTitle, subtitleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.Label(confirmationMessage, normalLabelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUI.enabled = !isLoading;
			if (GUILayout.Button("Cancel", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(30f),
				GUILayout.Width(120f)
			}))
			{
				ClearPendingConfirmation();
			}
			GUI.enabled = !isLoading;
			if (GUILayout.Button("Confirm", dangerButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(30f),
				GUILayout.Width(120f)
			}))
			{
				ExecutePendingConfirmation();
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		internal static void TryAttachPauseMenuButton(PauseMenuMainPage pauseMenuPage)
		{
			Instance?.AttachPauseMenuButton(pauseMenuPage);
		}

		private void AttachPauseMenuButton(PauseMenuMainPage pauseMenuPage)
		{
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_00f7: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pauseMenuPage == (Object)null)
			{
				return;
			}
			try
			{
				object? obj = AccessTools.Field(typeof(PauseMenuMainPage), "m_settingsButton")?.GetValue(pauseMenuPage);
				Button val = (Button)((obj is Button) ? obj : null);
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)((Component)val).transform.parent == (Object)null)
				{
					return;
				}
				Transform parent = ((Component)val).transform.parent;
				Transform val2 = parent.Find("PeakSaveManagerButton");
				Button component;
				if ((Object)(object)val2 == (Object)null)
				{
					GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false);
					((Object)val3).name = "PeakSaveManagerButton";
					Transform transform = ((Component)val).transform;
					RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					Transform transform2 = val3.transform;
					RectTransform val5 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
					if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null)
					{
						val5.anchorMin = val4.anchorMin;
						val5.anchorMax = val4.anchorMax;
						val5.pivot = val4.pivot;
						val5.sizeDelta = val4.sizeDelta;
						((Transform)val5).localScale = ((Transform)val4).localScale;
						Vector2 anchoredPosition = val4.anchoredPosition;
						Rect rect = val4.rect;
						val5.anchoredPosition = anchoredPosition + new Vector2(0f, 0f - Mathf.Max(50f, ((Rect)(ref rect)).height + 8f));
					}
					val3.transform.SetSiblingIndex(((Component)val).transform.GetSiblingIndex() + 1);
					MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true);
					foreach (MonoBehaviour val6 in componentsInChildren)
					{
						if ((Object)(object)val6 != (Object)null && ((object)val6).GetType().Name == "LocalizedText")
						{
							Object.Destroy((Object)(object)val6);
						}
					}
					SetPauseMenuButtonText(val3, "SAVE MANAGER");
					component = val3.GetComponent<Button>();
				}
				else
				{
					component = ((Component)val2).GetComponent<Button>();
				}
				if (!((Object)(object)component == (Object)null))
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
					((UnityEvent)component.onClick).AddListener((UnityAction)delegate
					{
						OpenPauseMenuSavePage(pauseMenuPage);
					});
					((Selectable)component).interactable = !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to attach pause menu save button: " + ex.Message));
			}
		}

		private void OpenPauseMenuSavePage(PauseMenuMainPage pauseMainPage)
		{
			//IL_001e: 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)
			//IL_00ac: Expected O, but got Unknown
			if ((Object)(object)pauseMainPage == (Object)null)
			{
				return;
			}
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				SetStatus("Only the host can open Save Manager.", Color.yellow, 2.5f);
				return;
			}
			UIPageHandler pageHandler = ((UIPage)pauseMainPage).GetPageHandler<UIPageHandler>();
			if ((Object)(object)pageHandler == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Pause menu page handler not found.");
				return;
			}
			object? obj = AccessTools.Field(typeof(PauseMenuMainPage), "m_settingsButton")?.GetValue(pauseMainPage);
			Button settingsButtonTemplate = (Button)((obj is Button) ? obj : null);
			SaveManagerPausePage saveManagerPausePage = EnsurePauseMenuSavePage(pageHandler, (UIPage)(object)pauseMainPage, settingsButtonTemplate);
			if ((Object)(object)saveManagerPausePage == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Save manager pause page could not be created.");
				return;
			}
			saveManagerPausePage.RefreshFromSource();
			pageHandler.TransistionToPage((UIPage)(object)saveManagerPausePage, (PageTransistion)new SetActivePageTransistion());
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}

		private SaveManagerPausePage EnsurePauseMenuSavePage(UIPageHandler pageHandler, UIPage mainPage, Button settingsButtonTemplate)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pageHandler == (Object)null || (Object)(object)mainPage == (Object)null)
			{
				return null;
			}
			if ((Object)(object)pauseMenuPage != (Object)null && (Object)(object)pauseMenuPageHandler == (Object)(object)pageHandler)
			{
				pauseMenuPage.Initialize(this, pageHandler, mainPage, settingsButtonTemplate);
				return pauseMenuPage;
			}
			SaveManagerPausePage saveManagerPausePage = pageHandler.GetPage<SaveManagerPausePage>() as SaveManagerPausePage;
			if ((Object)(object)saveManagerPausePage != (Object)null)
			{
				pauseMenuPage = saveManagerPausePage;
				pauseMenuPageHandler = pageHandler;
				pauseMenuMainPage = mainPage;
				pauseMenuButtonTemplate = settingsButtonTemplate;
				pauseMenuPage.Initialize(this, pageHandler, mainPage, settingsButtonTemplate);
				return pauseMenuPage;
			}
			GameObject val = new GameObject("PauseMenuSaveManagerPage", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(SaveManagerPausePage)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent(((Component)pageHandler).transform, false);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			((Graphic)val.GetComponent<Image>()).color = new Color(0.02f, 0.05f, 0.1f, 0.75f);
			SaveManagerPausePage component2 = val.GetComponent<SaveManagerPausePage>();
			AccessTools.Field(typeof(UIPage), "pageHandler")?.SetValue(component2, pageHandler);
			component2.Initialize(this, pageHandler, mainPage, settingsButtonTemplate);
			val.SetActive(false);
			object obj = AccessTools.Field(typeof(UIPageHandler), "_pages")?.GetValue(pageHandler);
			if (obj != null)
			{
				obj.GetType().GetMethod("Remove", new Type[1] { typeof(Type) })?.Invoke(obj, new object[1] { typeof(SaveManagerPausePage) });
				MethodInfo method = obj.GetType().GetMethod("Add", new Type[2]
				{
					typeof(Type),
					typeof(UIPage)
				});
				if (method != null)
				{
					method.Invoke(obj, new object[2]
					{
						typeof(SaveManagerPausePage),
						component2
					});
				}
				else
				{
					obj.GetType().GetMethod("Add")?.Invoke(obj, new object[2]
					{
						typeof(SaveManagerPausePage),
						component2
					});
				}
			}
			pauseMenuPage = component2;
			pauseMenuPageHandler = pageHandler;
			pauseMenuMainPage = mainPage;
			pauseMenuButtonTemplate = settingsButtonTemplate;
			return component2;
		}

		internal static bool TryInterceptPauseQuit(PauseMenuMainPage page)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance.InterceptPauseQuit(page);
			}
			return false;
		}

		private bool InterceptPauseQuit(PauseMenuMainPage page)
		{
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			if (allowVanillaQuitClick || (Object)(object)page == (Object)null)
			{
				return false;
			}
			if (!CanSaveNow(showReason: false))
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(PauseMenuMainPage), "confirmWindow");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(PauseMenuMainPage), "m_confirmOkButton");
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(PauseMenuMainPage), "m_confirmCancelButton");
			FieldInfo fieldInfo4 = AccessTools.Field(typeof(PauseMenuMainPage), "confirmText");
			MenuWindow confirmWindow = default(MenuWindow);
			ref MenuWindow reference = ref confirmWindow;
			object? obj = fieldInfo?.GetValue(page);
			reference = (MenuWindow)((obj is MenuWindow) ? obj : null);
			object? obj2 = fieldInfo2?.GetValue(page);
			Button val = (Button)((obj2 is Button) ? obj2 : null);
			object? obj3 = fieldInfo3?.GetValue(page);
			Button val2 = (Button)((obj3 is Button) ? obj3 : null);
			object? obj4 = fieldInfo4?.GetValue(page);
			LocalizedText val3 = (LocalizedText)((obj4 is LocalizedText) ? obj4 : null);
			if ((Object)(object)confirmWindow == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return false;
			}
			quitPendingSaveDecision = true;
			quitPendingPage = page;
			OpenMenuWindow(confirmWindow);
			if (val3 != null)
			{
				val3.SetText("Would you like to save your game before quitting?");
			}
			SetPauseMenuButtonText(((Component)val).gameObject, "YES");
			SetPauseMenuButtonText(((Component)val2).gameObject, "NO");
			((UnityEventBase)val.onClick).RemoveAllListeners();
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				CloseMenuWindow(confirmWindow);
				OpenPauseMenuSavePage(page);
			});
			((UnityEventBase)val2.onClick).RemoveAllListeners();
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				CloseMenuWindow(confirmWindow);
				quitPendingSaveDecision = false;
				quitPendingPage = null;
				ContinueWithVanillaQuit(page);
			});
			return true;
		}

		private void ContinueWithVanillaQuit(PauseMenuMainPage page)
		{
			if ((Object)(object)page == (Object)null)
			{
				return;
			}
			try
			{
				allowVanillaQuitClick = true;
				MethodInfo methodInfo = AccessTools.Method(typeof(PauseMenuMainPage), "Quit", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					methodInfo.Invoke(page, null);
				}
				else
				{
					AccessTools.Method(typeof(PauseMenuMainPage), "OnQuitClicked", (Type[])null, (Type[])null)?.Invoke(page, null);
				}
			}
			finally
			{
				allowVanillaQuitClick = false;
			}
		}

		private static void SetPauseMenuButtonText(GameObject buttonObject, string text)
		{
			if ((Object)(object)buttonObject == (Object)null)
			{
				return;
			}
			TMP_Text componentInChildren = buttonObject.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
				componentInChildren.enableAutoSizing = true;
				componentInChildren.fontSizeMin = 13f;
				componentInChildren.fontSizeMax = 21f;
				componentInChildren.fontStyle = (FontStyles)16;
				componentInChildren.overflowMode = (TextOverflowModes)1;
				return;
			}
			Text componentInChildren2 = buttonObject.GetComponentInChildren<Text>(true);
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.text = text;
				componentInChildren2.fontStyle = (FontStyle)0;
				componentInChildren2.resizeTextForBestFit = true;
				componentInChildren2.resizeTextMinSize = 13;
				componentInChildren2.resizeTextMaxSize = 21;
			}
		}

		private static void OpenMenuWindow(MenuWindow window)
		{
			if ((Object)(object)window == (Object)null)
			{
				return;
			}
			try
			{
				MenuWindowOpenMethod?.Invoke(window, null);
			}
			catch
			{
				((Component)window).gameObject.SetActive(true);
			}
		}

		private static void CloseMenuWindow(MenuWindow window)
		{
			if ((Object)(object)window == (Object)null)
			{
				return;
			}
			try
			{
				MenuWindowCloseMethod?.Invoke(window, null);
			}
			catch
			{
				((Component)window).gameObject.SetActive(false);
			}
		}

		private static int GetLuggageState(Luggage luggage)
		{
			if ((Object)(object)luggage == (Object)null || LuggageStateField == null)
			{
				return 0;
			}
			try
			{
				object value = LuggageStateField.GetValue(luggage);
				return (value != null) ? Convert.ToInt32(value, CultureInfo.InvariantCulture) : 0;
			}
			catch
			{
				return 0;
			}
		}

		private static void SetLuggageStateRaw(Luggage luggage, int rawState)
		{
			if ((Object)(object)luggage == (Object)null || LuggageStateField == null)
			{
				return;
			}
			int num = Mathf.Max(0, rawState);
			try
			{
				Type fieldType = LuggageStateField.FieldType;
				if (fieldType != null && fieldType.IsEnum)
				{
					Array values = Enum.GetValues(fieldType);
					if (values != null && values.Length > 0)
					{
						int num2 = (from object value in values
							select Convert.ToInt32(value, CultureInfo.InvariantCulture)).DefaultIfEmpty(0).Max();
						num = Mathf.Clamp(num, 0, num2);
					}
				}
				object value2 = ((fieldType != null && fieldType.IsEnum) ? Enum.ToObject(fieldType, num) : ((object)num));
				LuggageStateField.SetValue(luggage, value2);
			}
			catch
			{
			}
		}

		private static PhotonView GetPhotonView(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			PhotonView component2 = component.GetComponent<PhotonView>();
			if ((Object)(object)component2 != (Object)null)
			{
				return component2;
			}
			return component.GetComponentInParent<PhotonView>();
		}

		private static void SetRespawnChestState(RespawnChest respawnChest, bool isSpent, bool hasRevivedPlayers)
		{
			if ((Object)(object)respawnChest == (Object)null)
			{
				return;
			}
			try
			{
				RespawnChestSetSpentMethod?.Invoke(respawnChest, new object[1] { isSpent });
				SetRespawnChestHasRevivedPlayers(respawnChest, hasRevivedPlayers);
			}
			catch
			{
			}
		}

		private static bool GetRespawnChestHasRevivedPlayers(RespawnChest respawnChest)
		{
			if ((Object)(object)respawnChest == (Object)null)
			{
				return false;
			}
			try
			{
				if (RespawnChestGetRevivedPlayersMethod?.Invoke(respawnChest, null) is bool result)
				{
					return result;
				}
				object obj = RespawnChestRevivedPlayersField?.GetValue(respawnChest);
				if (obj is bool)
				{
					return (bool)obj;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void SetRespawnChestHasRevivedPlayers(RespawnChest respawnChest, bool hasRevivedPlayers)
		{
			if ((Object)(object)respawnChest == (Object)null)
			{
				return;
			}
			try
			{
				if (RespawnChestSetRevivedPlayersMethod != null)
				{
					RespawnChestSetRevivedPlayersMethod.Invoke(respawnChest, new object[1] { hasRevivedPlayers });
				}
				else
				{
					RespawnChestRevivedPlayersField?.SetValue(respawnChest, hasRevivedPlayers);
				}
			}
			catch
			{
			}
		}

		private static string GetDayNightTimeString(DayNightManager dayNight)
		{
			if ((Object)(object)dayNight == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				if ((DayNightTimeStringGetterMethod?.Invoke(dayNight, null) ?? DayNightTimeStringField?.GetValue(dayNight)) is string result)
				{
					return result;
				}
			}
			catch
			{
			}
			return string.Empty;
		}

		private static void SetDayNightTimeString(DayNightManager dayNight, string timeString)
		{
			if ((Object)(object)dayNight == (Object)null || string.IsNullOrWhiteSpace(timeString))
			{
				return;
			}
			try
			{
				if (DayNightTimeStringSetterMethod != null)
				{
					DayNightTimeStringSetterMethod.Invoke(dayNight, new object[1] { timeString });
				}
				else
				{
					DayNightTimeStringField?.SetValue(dayNight, timeString);
				}
			}
			catch
			{
			}
		}

		private bool CanSaveNow(bool showReason)
		{
			//IL_0010: 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)
			if (IsInAirportScene())
			{
				if (showReason)
				{
					SetStatus("You cannot save in the Airport.", Color.yellow, 3f);
				}
				return false;
			}
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
			{
				if (showReason)
				{
					SetStatus("Only host can save shared runs.", Color.yellow, 3f);
				}
				return false;
			}
			return true;
		}

		private bool TrySaveGame(string saveName)
		{
			//IL_00f7: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSaveNow(showReason: true))
			{
				return false;
			}
			try
			{
				if (!EnsureSaveDirectoryReady(showStatus: true))
				{
					return false;
				}
				string text = NormalizeSaveDisplayName(saveName);
				SaveEnvelope saveEnvelope = CaptureSnapshot(text);
				if (saveEnvelope.players == null || saveEnvelope.players.Count == 0)
				{
					SetStatus("Could not find an active player to save. Try again in-run.", Color.yellow, 4f);
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Save aborted: snapshot captured 0 players.");
					return false;
				}
				string text2 = ResolveSavePathForName(text);
				string contents = JsonConvert.SerializeObject((object)saveEnvelope, (Formatting)1);
				File.WriteAllText(text2, contents);
				if (text.Equals("Autosave", StringComparison.OrdinalIgnoreCase))
				{
					CleanupLegacyAutosaves(text2);
				}
				RefreshSaveFileList();
				SetStatus("Saved: " + text, Color.green, 3f);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Saved run to " + text2));
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Save failed: {ex}");
				SetStatus(BuildSaveFailureStatus(ex), Color.red, 6f);
				return false;
			}
		}

		private bool TryOverwriteSave(string fullPath, string saveNameHint)
		{
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSaveNow(showReason: true))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(fullPath))
			{
				SetStatus("Invalid save path.", Color.red, 4f);
				return false;
			}
			try
			{
				if (!EnsureSaveDirectoryReady(showStatus: true))
				{
					return false;
				}
				string text = NormalizeSaveDisplayName(string.IsNullOrWhiteSpace(saveNameHint) ? Path.GetFileNameWithoutExtension(fullPath) : saveNameHint.Trim());
				SaveEnvelope saveEnvelope = CaptureSnapshot(text);
				if (saveEnvelope.players == null || saveEnvelope.players.Count == 0)
				{
					SetStatus("Could not find an active player to overwrite from. Try again in-run.", Color.yellow, 4f);
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Overwrite aborted for '" + fullPath + "': snapshot captured 0 players."));
					return false;
				}
				string contents = JsonConvert.SerializeObject((object)saveEnvelope, (Formatting)1);
				File.WriteAllText(fullPath, contents);
				RefreshSaveFileList();
				SetStatus("Overwrote save: " + text, Color.green, 3f);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Overwrote run at " + fullPath));
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Overwrite failed for '{fullPath}': {ex}");
				SetStatus(BuildSaveFailureStatus(ex), Color.red, 6f);
				return false;
			}
		}

		internal void UiRefreshSaveList()
		{
			RefreshSaveFileList();
		}

		internal List<SaveListEntry> UiGetSaveEntries()
		{
			return new List<SaveListEntry>(saveEntries);
		}

		internal void UiQuickSave()
		{
			bool saveSucceeded = TrySaveGame("Quick Save");
			MaybeCompletePendingQuitAfterSave(saveSucceeded);
		}

		internal void UiNamedSave(string saveName)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(saveName))
			{
				SetStatus("Enter a save name first.", Color.yellow, 3f);
				return;
			}
			bool saveSucceeded = TrySaveGame(saveName.Trim());
			MaybeCompletePendingQuitAfterSave(saveSucceeded);
		}

		internal void UiLoadSave(string fullPath)
		{
			StartLoadFromUi(fullPath);
		}

		internal void UiOverwriteSave(string fullPath, string saveNameHint)
		{
			bool saveSucceeded = TryOverwriteSave(fullPath, saveNameHint);
			MaybeCompletePendingQuitAfterSave(saveSucceeded);
		}

		internal void UiDeleteSave(string fullPath)
		{
			TryDeleteSave(fullPath);
		}

		internal bool UiCanSaveNow(bool showReason = false)
		{
			return CanSaveNow(showReason);
		}

		internal bool UiIsLoading()
		{
			return isLoading;
		}

		internal string UiCurrentStatus()
		{
			if (string.IsNullOrWhiteSpace(statusMessage))
			{
				return string.Empty;
			}
			if (statusMessageUntil <= Time.unscaledTime)
			{
				return string.Empty;
			}
			return statusMessage;
		}

		internal bool UiHasPendingQuitSaveDecision()
		{
			return quitPendingSaveDecision;
		}

		internal void UiQuickSaveAndQuit()
		{
			if (CanSaveNow(showReason: true) && TrySaveGame("Quick Save"))
			{
				CompletePendingQuit();
			}
		}

		internal void UiNamedSaveAndQuit(string saveName)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (CanSaveNow(showReason: true))
			{
				if (string.IsNullOrWhiteSpace(saveName))
				{
					SetStatus("Enter a save name before Save & Quit.", Color.yellow, 3f);
				}
				else if (TrySaveGame(saveName.Trim()))
				{
					CompletePendingQuit();
				}
			}
		}

		internal void UiQuitWithoutSaving()
		{
			CompletePendingQuit();
		}

		internal void UiCancelPendingQuit()
		{
			quitPendingSaveDecision = false;
			quitPendingPage = null;
		}

		private void MaybeCompletePendingQuitAfterSave(bool saveSucceeded)
		{
			if (saveSucceeded && quitPendingSaveDecision)
			{
				CompletePendingQuit();
			}
		}

		private void CompletePendingQuit()
		{
			PauseMenuMainPage page = quitPendingPage;
			quitPendingSaveDecision = false;
			quitPendingPage = null;
			ContinueWithVanillaQuit(page);
		}

		private SaveEnvelope CaptureSnapshot(string saveName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected I4, but got Unknown
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			LevelGeneration val = Object.FindFirstObjectByType<LevelGeneration>();
			int levelSeed = (((Object)(object)val != (Object)null) ? val.seed : 0);
			int currentSegment = 0;
			Segment val2 = (Segment)0;
			string currentSegmentName = ((object)(Segment)(ref val2)).ToString();
			if (MapHandler.Exists)
			{
				MapHandler val3 = Object.FindFirstObjectByType<MapHandler>();
				if ((Object)(object)val3 != (Object)null)
				{
					Segment currentSegment2 = val3.GetCurrentSegment();
					currentSegment = (int)currentSegment2;
					currentSegmentName = ((object)(Segment)(ref currentSegment2)).ToString();
				}
			}
			int? dailyLevelIndex = null;
			string biomeId = string.Empty;
			try
			{
				NextLevelService service = GameHandler.GetService<NextLevelService>();
				if (service != null && service.HasReceivedLevelIndex)
				{
					dailyLevelIndex = service.NextLevelIndexOrFallback;
					biomeId = SingletonAsset<MapBaker>.Instance.GetBiomeID(dailyLevelIndex.Value + NextLevelService.debugLevelIndexOffset);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not capture NextLevelService metadata: " + ex.Message));
			}
			string text = ResolveLevelName(name, dailyLevelIndex);
			int? levelNumber = ParseLevelNumber(text);
			CaptureRunMetadata(out var runDay, out var runTimeSeconds, out var runTimerActive, out var timeOfDay, out var inGameTime);
			SaveEnvelope saveEnvelope = new SaveEnvelope
			{
				pluginGuid = "com.lucasandersen.peakallyouneedsavemanager",
				pluginVersion = "1.0.0",
				metadata = new SaveMetadata
				{
					saveName = saveName,
					savedAtUtc = DateTime.UtcNow,
					sceneName = name,
					levelName = text,
					levelNumber = levelNumber,
					dailyLevelIndex = dailyLevelIndex,
					biomeId = biomeId,
					levelSeed = levelSeed,
					currentSegment = currentSegment,
					currentSegmentName = currentSegmentName,
					ascent = Ascents.currentAscent,
					runDay = runDay,
					runTimeSeconds = runTimeSeconds,
					runTimerActive = runTimerActive,
					timeOfDay = timeOfDay,
					inGameTime = inGameTime
				}
			};
			CapturePlayers(saveEnvelope.players);
			saveEnvelope.metadata.playerCount = saveEnvelope.players.Count;
			CaptureCampfires(saveEnvelope.campfires);
			CaptureLuggageStates(saveEnvelope.luggageStates);
			CaptureContainerStates(saveEnvelope.containerStates);
			CaptureGroundItems(saveEnvelope.groundItems);
			CaptureWorldObjects(saveEnvelope.worldObjects);
			return saveEnvelope;
		}

		private static void CaptureRunMetadata(out int? runDay, out float? runTimeSeconds, out bool? runTimerActive, out float? timeOfDay, out string inGameTime)
		{
			runDay = null;
			runTimeSeconds = null;
			runTimerActive = null;
			timeOfDay = null;
			inGameTime = string.Empty;
			try
			{
				DayNightManager val = DayNightManager.instance ?? Object.FindFirstObjectByType<DayNightManager>();
				if ((Object)(object)val != (Object)null)
				{
					runDay = Mathf.Max(0, val.dayCount);
					timeOfDay = val.timeOfDay;
					string dayNightTimeString = GetDayNightTimeString(val);
					if (!string.IsNullOrWhiteSpace(dayNightTimeString))
					{
						inGameTime = dayNightTimeString;
					}
					else
					{
						inGameTime = val.FloatToTimeString(val.timeOfDay);
					}
				}
			}
			catch (Exception ex)
			{
				SaveManagerPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)("Could not capture day/night metadata: " + ex.Message));
				}
			}
			try
			{
				RunManager val2 = RunManager.Instance ?? Object.FindFirstObjectByType<RunManager>();
				if ((Object)(object)val2 != (Object)null)
				{
					runTimeSeconds = Mathf.Max(0f, val2.timeSinceRunStarted);
					runTimerActive = TryGetRunTimerActive(val2);
				}
			}
			catch (Exception ex2)
			{
				SaveManagerPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogWarning((object)("Could not capture run timer metadata: " + ex2.Message));
				}
			}
		}

		private static bool? TryGetRunTimerActive(RunManager runManager)
		{
			if ((Object)(object)runManager == (Object)null || RunManagerTimerActiveField == null)
			{
				return null;
			}
			try
			{
				object value = RunManagerTimerActiveField.GetValue(runManager);
				if (value is bool)
				{
					return (bool)value;
				}
			}
			catch
			{
			}
			return null;
		}

		private void CapturePlayers(List<PlayerSnapshot> output)
		{
			Player[] array = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
			foreach (Player player in array)
			{
				try
				{
					output.Add(CapturePlayer(player));
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to snapshot player: " + ex.Message));
				}
			}
			if (output.Count > 0)
			{
				return;
			}
			Character[] array2 = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
			foreach (Character val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Player val2 = ((Component)val).GetComponent<Player>() ?? ((Component)val).GetComponentInParent<Player>();
				if (!((Object)(object)val2 == (Object)null))
				{
					try
					{
						output.Add(CapturePlayer(val2));
					}
					catch (Exception ex2)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to snapshot fallback player: " + ex2.Message));
					}
					if (output.Count > 0)
					{
						break;
					}
				}
			}
			if (output.Count > 0)
			{
				return;
			}
			foreach (Player item in EnumeratePlayersFromHandler())
			{
				if (!((Object)(object)item == (Object)null))
				{
					try
					{
						output.Add(CapturePlayer(item));
					}
					catch (Exception ex3)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to snapshot handler fallback player: " + ex3.Message));
					}
					if (output.Count > 0)
					{
						break;
					}
				}
			}
		}

		[IteratorStateMachine(typeof(<EnumeratePlayersFromHandler>d__155))]
		private static IEnumerable<Player> EnumeratePlayersFromHandler()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnumeratePlayersFromHandler>d__155(-2);
		}

		private PlayerSnapshot CapturePlayer(Player player)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			string text = "Unknown";
			int actorNumber = 0;
			PhotonView photonView = GetPhotonView((Component)(object)player);
			if ((Object)(object)photonView == (Object)null && (Object)(object)player != (Object)null && (Object)(object)player.character != (Object)null)
			{
				photonView = GetPhotonView((Component)(object)player.character);
			}
			if ((Object)(object)photonView != (Object)null)
			{
				Player owner = photonView.Owner;
				if (owner != null)
				{
					text = owner.NickName;
					actorNumber = owner.ActorNumber;
				}
				else
				{
					actorNumber = photonView.OwnerActorNr;
				}
			}
			Character character = player.character;
			Vector3 source = (((Object)(object)character != (Object)null) ? GetCharacterPosition(character) : ((Component)player).transform.position);
			Vector3 source2 = (((Object)(object)character != (Object)null) ? ((Component)character).transform.eulerAngles : ((Component)player).transform.eulerAngles);
			CaptureCharacterVelocity(character, out var velocity, out var angularVelocity);
			InventorySnapshot inventory;
			try
			{
				inventory = CaptureInventory(player, character);
			}
			catch (Exception ex)
			{
				SaveManagerPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)("Inventory capture fallback for player '" + text + "': " + ex.Message));
				}
				inventory = new InventorySnapshot();
			}
			return new PlayerSnapshot
			{
				playerName = text,
				actorNumber = actorNumber,
				position = new Vector3Snapshot(source),
				rotation = new Vector3Snapshot(source2),
				velocity = new Vector3Snapshot(velocity),
				angularVelocity = new Vector3Snapshot(angularVelocity),
				character = CaptureCharacter(character),
				inventory = inventory
			};
		}

		private static CharacterSnapshot CaptureCharacter(Character character)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			CharacterSnapshot characterSnapshot = new CharacterSnapshot();
			if ((Object)(object)character == (Object)null)
			{
				return characterSnapshot;
			}
			characterSnapshot.dead = character.data.dead;
			characterSnapshot.passedOut = character.data.passedOut;
			characterSnapshot.fullyPassedOut = character.data.fullyPassedOut;
			characterSnapshot.isGrounded = character.data.isGrounded;
			characterSnapshot.isClimbing = character.data.isClimbing;
			characterSnapshot.isRopeClimbing = character.data.isRopeClimbing;
			characterSnapshot.isVineClimbing = character.data.isVineClimbing;
			characterSnapshot.isSprinting = character.data.isSprinting;
			characterSnapshot.currentStamina = character.data.currentStamina;
			characterSnapshot.extraStamina = character.data.extraStamina;
			characterSnapshot.sinceGrounded = character.data.sinceGrounded;
			characterSnapshot.lookValues = new Vector2Snapshot(character.data.lookValues);
			characterSnapshot.checkpointFlagPaths = CaptureCharacterCheckpointPaths(character);
			characterSnapshot.statuses = CaptureCharacterStatuses(character);
			return characterSnapshot;
		}

		private static List<string> CaptureCharacterCheckpointPaths(Character character)
		{
			List<string> list = new List<string>();
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || CharacterDataCheckpointFlagsField == null)
			{
				return list;
			}
			try
			{
				if (CharacterDataCheckpointFlagsField.GetValue(character.data) is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						CheckpointFlag val = (CheckpointFlag)((item is CheckpointFlag) ? item : null);
						if (val != null && (Object)(object)val != (Object)null)
						{
							string text = BuildTransformPath(((Component)val).transform);
							if (!string.IsNullOrWhiteSpace(text))
							{
								list.Add(text);
							}
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		private static void CaptureCharacterVelocity(Character character, out Vector3 velocity, out Vector3 angularVelocity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			velocity = Vector3.zero;
			angularVelocity = Vector3.zero;
			if (!((Object)(object)character == (Object)null))
			{
				Rigidbody val = ((character.refs != null && (Object)(object)character.refs.hip != (Object)null) ? character.refs.hip.Rig : null);
				if ((Object)(object)val != (Object)null)
				{
					velocity = val.linearVelocity;
					angularVelocity = val.angularVelocity;
				}
				else if ((Object)(object)character.data != (Object)null)
				{
					velocity = character.data.avarageVelocity;
					angularVelocity = character.data.avarageLastFrameVelocity;
				}
			}
		}

		private static List<CharacterStatusSnapshot> CaptureCharacterStatuses(Character character)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			List<CharacterStatusSnapshot> list = new List<CharacterStatusSnapshot>();
			if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null)
			{
				return list;
			}
			CharacterAfflictions afflictions = character.refs.afflictions;
			Array values = Enum.GetValues(typeof(STATUSTYPE));
			for (int i = 0; i < values.Length; i++)
			{
				STATUSTYPE val = (STATUSTYPE)values.GetValue(i);
				if (!SkippedSavedStatuses.Contains(val))
				{
					float currentStatus = afflictions.GetCurrentStatus(val);
					if (!(currentStatus <= 0f))
					{
						list.Add(new CharacterStatusSnapshot
						{
							statusType = ((object)(STATUSTYPE)(ref val)).ToString(),
							amount = currentStatus
						});
					}
				}
			}
			return list;
		}

		private static InventorySnapshot CaptureInventory(Player player, Character character)
		{
			InventorySnapshot inventorySnapshot = new InventorySnapshot();
			if ((Object)(object)player == (Object)null)
			{
				return inventorySnapshot;
			}
			if (player.itemSlots != null)
			{
				for (int i = 0; i < player.itemSlots.Length; i++)
				{
					inventorySnapshot.mainSlots.Add(CaptureItemSlot(player.itemSlots[i]));
				}
			}
			inventorySnapshot.tempSlot = CaptureItemSlot(player.tempFullSlot);
			inventorySnapshot.hasBackpack = player.backpackSlot != null && player.backpackSlot.hasBackpack;
			if (inventorySnapshot.hasBackpack && TryGetBackpackData(player, out var backpackData) && backpackData != null && backpackData.itemSlots != null)
			{
				for (int j = 0; j < backpackData.itemSlots.Length; j++)
				{
					inventorySnapshot.backpackSlots.Add(CaptureItemSlot(backpackData.itemSlots[j]));
				}
			}
			CaptureEquippedSelection(player, character, inventorySnapshot);
			return inventorySnapshot;
		}

		private static void CaptureEquippedSelection(Player player, Character character, InventorySnapshot snapshot)
		{
			if (snapshot == null)
			{
				return;
			}
			Item val = (((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null) ? character.data.currentItem : null);
			if ((Object)(object)val != (Object)null)
			{
				snapshot.heldItemId = val.itemID;
			}
			if (TryGetCharacterSelectedSlot(character, out var selectedSlot))
			{
				snapshot.selectedSlotId = selectedSlot;
				if ((Object)(object)player != (Object)null && player.itemSlots != null && selectedSlot >= 0 && selectedSlot < player.itemSlots.Length)
				{
					snapshot.equippedMainSlotIndex = selectedSlot;
				}
			}
			if (!snapshot.equippedMainSlotIndex.HasValue && snapshot.heldItemId != ushort.MaxValue && (Object)(object)player != (Object)null && player.itemSlots != null)
			{
				for (int i = 0; i < player.itemSlots.Length; i++)
				{
					ItemSlot val2 = player.itemSlots[i];
					if (val2 != null && (Object)(object)val2.prefab != (Object)null && val2.prefab.itemID == snapshot.heldItemId)
					{
						snapshot.equippedMainSlotIndex = i;
						break;
					}
				}
			}
			if (snapshot.heldItemId != ushort.MaxValue && (Object)(object)player != (Object)null && player.tempFullSlot != null && (Object)(object)player.tempFullSlot.prefab != (Object)null && player.tempFullSlot.prefab.itemID == snapshot.heldItemId)
			{
				snapshot.equippedTempSlot = true;
			}
			if (snapshot.heldItemId == ushort.MaxValue || !((Object)(object)player != (Object)null) || !TryGetBackpackData(player, out var backpackData) || backpackData == null || backpackData.itemSlots == null)
			{
				return;
			}
			for (int j = 0; j < backpackData.itemSlots.Length; j++)
			{
				ItemSlot val3 = backpackData.itemSlots[j];
				if (val3 != null && (Object)(object)val3.prefab != (Object)null && val3.prefab.itemID == snapshot.heldItemId)
				{
					snapshot.equippedBackpackSlotIndex = j;
					break;
				}
			}
		}

		private static ItemSlotSnapshot CaptureItemSlot(ItemSlot slot)
		{
			if (slot == null || (Object)(object)slot.prefab == (Object)null)
			{
				return ItemSlotSnapshot.Empty();
			}
			ItemSlotSnapshot itemSlotSnapshot = new ItemSlotSnapshot
			{
				itemId = slot.prefab.itemID
			};
			CaptureItemUsageData(slot.data, itemSlotSnapshot);
			return itemSlotSnapshot;
		}

		private static void CaptureItemUsageData(ItemInstanceData data, ItemSlotSnapshot snapshot)
		{
			if (data != null && snapshot != null)
			{
				if (TryReadItemUsageInt(data, (DataEntryKey)2, out var value))
				{
					snapshot.itemUses = value;
				}
				if (TryReadItemUsageInt(data, (DataEntryKey)12, out var value2))
				{
					snapshot.petterItemUses = value2;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)11, out var value3))
				{
					snapshot.useRemainingPercentage = value3;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)8, out var value4))
				{
					snapshot.used = value4;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)10, out var value5))
				{
					snapshot.fuel = value5;
				}
				if (TryReadItemUsageInt(data, (DataEntryKey)1, out var value6))
				{
					snapshot.cookedAmount = value6;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)3, out var value7))
				{
					snapshot.flareActive = value7;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)13, out var value8))
				{
					snapshot.screamTime = value8;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)5, out var value9))
				{
					snapshot.spawnedBees = value9;
				}
				CaptureGenericItemData(data, snapshot.dataEntries);
			}
		}

		private static void CaptureItemUsageData(ItemInstanceData data, GroundItemSnapshot snapshot)
		{
			if (data != null && snapshot != null)
			{
				if (TryReadItemUsageInt(data, (DataEntryKey)2, out var value))
				{
					snapshot.itemUses = value;
				}
				if (TryReadItemUsageInt(data, (DataEntryKey)12, out var value2))
				{
					snapshot.petterItemUses = value2;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)11, out var value3))
				{
					snapshot.useRemainingPercentage = value3;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)8, out var value4))
				{
					snapshot.used = value4;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)10, out var value5))
				{
					snapshot.fuel = value5;
				}
				if (TryReadItemUsageInt(data, (DataEntryKey)1, out var value6))
				{
					snapshot.cookedAmount = value6;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)3, out var value7))
				{
					snapshot.flareActive = value7;
				}
				if (TryReadItemUsageFloat(data, (DataEntryKey)13, out var value8))
				{
					snapshot.screamTime = value8;
				}
				if (TryReadItemUsageBool(data, (DataEntryKey)5, out var value9))
				{
					snapshot.spawnedBees = value9;
				}
				CaptureGenericItemData(data, snapshot.dataEntries);
			}
		}

		private static bool TryReadItemUsageInt(ItemInstanceData data, DataEntryKey key, out int value)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			value = 0;
			if (!TryGetRawDataEntry(data, key, out var value2) || value2 == null)
			{
				return false;
			}
			OptionableIntItemData val = (OptionableIntItemData)(object)((value2 is OptionableIntItemData) ? value2 : null);
			if (val != null && TryReadOptionableInt(val, out var value3))
			{
				value = value3;
				return true;
			}
			IntItemData val2 = (IntItemData)(object)((value2 is IntItemData) ? value2 : null);
			if (val2 != null)
			{
				value = val2.Value;
				return true;
			}
			FloatItemData val3 = (FloatItemData)(object)((value2 is FloatItemData) ? value2 : null);
			if (val3 != null)
			{
				value = Mathf.RoundToInt(val3.Value);
				return true;
			}
			BoolItemData val4 = (BoolItemData)(object)((value2 is BoolItemData) ? value2 : null);
			if (val4 != null)
			{
				value = (val4.Value ? 1 : 0);
				return true;
			}
			return false;
		}

		private static bool TryReadItemUsageFloat(ItemInstanceData data, DataEntryKey key, out float value)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			value = 0f;
			if (!TryGetRawDataEntry(data, key, out var value2) || value2 == null)
			{
				return false;
			}
			OptionableIntItemData val = (OptionableIntItemData)(object)((value2 is OptionableIntItemData) ? value2 : null);
			if (val != null && TryReadOptionableInt(val, out var value3))
			{
				value = value3;
				return true;
			}
			FloatItemData val2 = (FloatItemData)(object)((value2 is FloatItemData) ? value2 : null);
			if (val2 != null)
			{
				value = val2.Value;
				return true;
			}
			IntItemData val3 = (IntItemData)(object)((value2 is IntItemData) ? value2 : null);
			if (val3 != null)
			{
				value = val3.Value;
				return true;
			}
			return false;
		}

		private static bool TryReadItemUsageBool(ItemInstanceData data, DataEntryKey key, out bool value)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			value = false;
			if (!TryGetRawDataEntry(data, key, out var value2) || value2 == null)
			{
				return false;
			}
			OptionableBoolItemData val = (OptionableBoolItemData)(object)((value2 is OptionableBoolItemData) ? value2 : null);
			if (val != null && TryReadOptionableBool(val, out var value3))
			{
				value = value3;
				return true;
			}
			BoolItemData val2 = (BoolItemData)(object)((value2 is BoolItemData) ? value2 : null);
			if (val2 != null)
			{
				value = val2.Value;
				return true;
			}
			IntItemData val3 = (IntItemData)(object)((value2 is IntItemData) ? value2 : null);
			if (val3 != null)
			{
				value = val3.Value > 0;
				return true;
			}
			return false;
		}

		private static bool TryReadOptionableInt(OptionableIntItemData data, out int value)
		{
			value = 0;
			if (data == null)
			{
				return false;
			}
			bool flag = true;
			if (OptionableIntHasDataField != null)
			{
				try
				{
					object value2 = OptionableIntHasDataField.GetValue(data);
					if (value2 is bool)
					{
						bool flag2 = (bool)value2;
						flag = flag2;
					}
				}
				catch
				{
				}
			}
			if (!flag)
			{
				return false;
			}
			if (OptionableIntValueField != null)
			{
				try
				{
					object value3 = OptionableIntValueField.GetValue(data);
					if (value3 is int)
					{
						int num = (int)value3;
						value = num;
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private static bool TryReadOptionableBool(OptionableBoolItemData data, out bool value)
		{
			value = false;
			if (data == null)
			{
				return false;
			}
			bool flag = true;
			if (OptionableBoolHasDataField != null)
			{
				try
				{
					object value2 = OptionableBoolHasDataField.GetValue(data);
					if (value2 is bool)
					{
						bool flag2 = (bool)value2;
						flag = flag2;
					}
				}
				catch
				{
				}
			}
			if (!flag)
			{
				return false;
			}
			if (OptionableBoolValueField != null)
			{
				try
				{
					object value3 = OptionableBoolValueField.GetValue(data);
					if (value3 is bool)
					{
						bool flag3 = (bool)value3;
						value = flag3;
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private static bool TryGetRawDataEntry(ItemInstanceData data, DataEntryKey key, out DataEntryValue value)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			value = null;
			if (data == null || data.data == null)
			{
				return false;
			}
			try
			{
				if (data.data.TryGetValue(key, out var value2) && value2 != null)
				{
					value = value2;
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void CaptureGenericItemData(ItemInstanceData data, List<ItemDataEntrySnapshot> output)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (data == null || output == null || data.data == null)
			{
				return;
			}
			output.Clear();
			foreach (KeyValuePair<DataEntryKey, DataEntryValue> datum in data.data)
			{
				if (TryCreateItemDataEntrySnapshot(datum.Key, datum.Value, out var snapshot))
				{
					output.Add(snapshot);
				}
			}
		}

		private static bool TryCreateItemDataEntrySnapshot(DataEntryKey key, DataEntryValue value, out ItemDataEntrySnapshot snapshot)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected I4, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			snapshot = null;
			if (value == null)
			{
				return false;
			}
			snapshot = new ItemDataEntrySnapshot
			{
				keyValue = (int)key,
				keyName = ((object)(DataEntryKey)(ref key)).ToString(),
				valueType = ((object)value).GetType().AssemblyQualifiedName,
				hasValue = true
			};
			IntItemData val = (IntItemData)(object)((value is IntItemData) ? value : null);
			if (val == null)
			{
				FloatItemData val2 = (FloatItemData)(object)((value is FloatItemData) ? value : null);
				if (val2 == null)
				{
					BoolItemData val3 = (BoolItemData)(object)((value is BoolItemData) ? value : null);
					if (val3 == null)
					{
						OptionableIntItemData val4 = (OptionableIntItemData)(object)((value is OptionableIntItemData) ? value : null);
						if (val4 == null)
						{
							OptionableBoolItemData val5 = (OptionableBoolItemData)(object)((value is OptionableBoolItemData) ? value : null);
							if (val5 == null)
							{
								ColorItemData val6 = (ColorItemData)(object)((value is ColorItemData) ? value : null);
								if (val6 == null)
								{
									BackpackData val7 = (BackpackData)(object)((value is BackpackData) ? value : null);
									if (val7 != null)
									{
										if (val7.itemSlots != null)
										{
											for (int i = 0; i < val7.itemSlots.Length; i++)
											{
												snapshot.backpackSlots.Add(CaptureItemSlot(val7.itemSlots[i]));
											}
										}
										return true;
									}
									try
									{
										snapshot.serializedJson = JsonConvert.SerializeObject((object)value, (Formatting)0);
										return true;
									}
									catch
									{
										snapshot.serializedJson = ((object)value).ToString();
										snapshot.stringValue = ((object)value).ToString();
										return true;
									}
								}
								snapshot.hasColorValue = true;
								snapshot.colorValue = new Vector4Snapshot(new Vector4(val6.Value.r, val6.Value.g, val6.Value.b, val6.Value.a));
								retu