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

BepInEx\plugins\TAYNSM\TAYNSM.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
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.1")]
	public sealed class SaveManagerPlugin : BaseUnityPlugin
	{
		private sealed class ProtectedGroundItemMarker
		{
			public ushort itemId;

			public Vector3 position;

			public float expiresAtRealtime;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass249_0
		{
			public bool restored;

			internal void <LoadSaveRoutine>b__0(bool success)
			{
				restored = success;
			}
		}

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

			private object <>2__current;

			public PlayerSnapshot snapshot;

			public Action<bool> completion;

			public SaveManagerPlugin <>4__this;

			public Player player;

			private bool <appliedAny>5__2;

			private Vector3 <targetPosition>5__3;

			private Vector3 <targetRotation>5__4;

			private bool <characterApplied>5__5;

			private bool <inventoryApplied>5__6;

			private bool <selectionApplied>5__7;

			private Character <stabilizedCharacter>5__8;

			private int <pass>5__9;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_037b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0388: Unknown result type (might be due to invalid IL or missing references)
				//IL_038e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0262: Unknown result type (might be due to invalid IL or missing references)
				//IL_026c: Expected O, but got Unknown
				//IL_065a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0660: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				Player val;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<appliedAny>5__2 = false;
					if (snapshot == null)
					{
						completion?.Invoke(obj: false);
						return false;
					}
					<targetPosition>5__3 = snapshot.position.ToUnity();
					<targetRotation>5__4 = snapshot.rotation.ToUnity();
					int valueOrDefault = (snapshot.inventory?.mainSlots?.Count((ItemSlotSnapshot slot) => slot?.HasItem() ?? false)).GetValueOrDefault();
					int valueOrDefault2 = (snapshot.inventory?.backpackSlots?.Count((ItemSlotSnapshot slot) => slot?.HasItem() ?? false)).GetValueOrDefault();
					<characterApplied>5__5 = false;
					<inventoryApplied>5__6 = snapshot.inventory == null;
					<selectionApplied>5__7 = snapshot.inventory == null;
					<stabilizedCharacter>5__8 = null;
					((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)($"Begin player restore for '{snapshot.playerName}' (Actor: {snapshot.actorNumber}) " + $"items(main={valueOrDefault}, backpack={valueOrDefault2}) " + "stamina=" + (snapshot.character?.currentStamina.ToString("0.###", CultureInfo.InvariantCulture) ?? "-") + " extra=" + (snapshot.character?.extraStamina.ToString("0.###", CultureInfo.InvariantCulture) ?? "-") + "."));
					<pass>5__9 = 0;
					goto IL_05c5;
				}
				case 1:
					<>1__state = -1;
					goto IL_027c;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_05c5:
					if (<pass>5__9 < 20)
					{
						if (<pass>5__9 > 0)
						{
							<>2__current = (object)new WaitForSeconds(0.75f);
							<>1__state = 1;
							return true;
						}
						goto IL_027c;
					}
					goto IL_05d2;
					IL_027c:
					val = saveManagerPlugin.ResolveRestoreTargetPlayer(snapshot, player);
					if (!IsUsablePlayerForRestore(val))
					{
						saveManagerPlugin.LogVerbose($"Player restore pass {<pass>5__9 + 1}: target player not usable yet for '{snapshot.playerName}'.");
					}
					else
					{
						Character character = val.character;
						if ((Object)(object)character == (Object)null)
						{
							saveManagerPlugin.LogVerbose($"Player restore pass {<pass>5__9 + 1}: character missing for '{snapshot.playerName}'.");
						}
						else
						{
							saveManagerPlugin.LogVerbose($"Player restore pass {<pass>5__9 + 1}: target='{Safe(((Object)val).name)}' " + "character='" + Safe(((Object)character).name) + "'");
							bool flag = false;
							if (!<characterApplied>5__5)
							{
								try
								{
									if (snapshot.character != null)
									{
										saveManagerPlugin.ApplyCharacterSnapshot(character, snapshot.character);
									}
									TryWarpCharacterViaRpc(character, <targetPosition>5__3);
									ApplyCharacterTransformSnapshot(character, <targetPosition>5__3, <targetRotation>5__4);
									PhotonView photonView = GetPhotonView((Component)(object)character);
									if ((Object)(object)character.data != (Object)null && snapshot.character != null && ((Object)(object)photonView == (Object)null || photonView.IsMine))
									{
										character.data.lookValues = snapshot.character.lookValues.ToUnity();
										RecalculateLookDirectionsMethod?.Invoke(character, null);
									}
									ApplyCharacterVelocity(character, snapshot.velocity, snapshot.angularVelocity);
									<characterApplied>5__5 = true;
									<stabilizedCharacter>5__8 = character;
									flag = true;
								}
								catch (Exception arg)
								{
									((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)$"Player character restore pass {<pass>5__9 + 1} failed for '{snapshot.playerName}': {arg}");
								}
							}
							if (snapshot.inventory != null)
							{
								if (!<inventoryApplied>5__6)
								{
									try
									{
										saveManagerPlugin.ApplyInventory(val, character, snapshot.inventory);
										<inventoryApplied>5__6 = true;
										flag = true;
									}
									catch (Exception arg2)
									{
										((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)$"Player inventory restore pass {<pass>5__9 + 1} failed for '{snapshot.playerName}': {arg2}");
									}
								}
								if (<inventoryApplied>5__6 && !<selectionApplied>5__7)
								{
									try
									{
										ApplyEquippedSelection(val, character, snapshot.inventory);
										<selectionApplied>5__7 = true;
										flag = true;
									}
									catch (Exception arg3)
									{
										((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)$"Player equipped-item restore pass {<pass>5__9 + 1} failed for '{snapshot.playerName}': {arg3}");
									}
								}
							}
							if (flag)
							{
								<appliedAny>5__2 = true;
								((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)$"Applied player snapshot pass {<pass>5__9 + 1}/{20} for '{snapshot.playerName}'.");
							}
							if (<characterApplied>5__5 & <inventoryApplied>5__6 & <selectionApplied>5__7)
							{
								<appliedAny>5__2 = true;
								saveManagerPlugin.LogVerbose($"Player restore completed all required sections on pass {<pass>5__9 + 1}. Ending retry loop early.");
								goto IL_05d2;
							}
						}
					}
					<pass>5__9++;
					goto IL_05c5;
					IL_05d2:
					if (!<appliedAny>5__2)
					{
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)$"No player snapshot passes succeeded for '{snapshot.playerName}' (Actor: {snapshot.actorNumber}).");
					}
					else
					{
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)$"Finished player restore for '{snapshot.playerName}' with {20} pass(es).");
					}
					if ((<appliedAny>5__2 & <characterApplied>5__5) && (Object)(object)<stabilizedCharacter>5__8 != (Object)null)
					{
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.StabilizeCharacterAfterLoad(<stabilizedCharacter>5__8, <targetPosition>5__3, <targetRotation>5__4));
						<>1__state = 2;
						return true;
					}
					break;
				}
				completion?.Invoke(<appliedAny>5__2);
				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 <DelayedOverflowTempEquipRoutine>d__281 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveManagerPlugin <>4__this;

			public int playerKey;

			public int generation;

			public Player player;

			public ushort expectedItemId;

			public Character character;

			private int <attempt>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Expected O, but got Unknown
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<attempt>5__2 = 0;
					goto IL_0334;
				case 2:
					{
						<>1__state = -1;
						goto IL_009e;
					}
					IL_0334:
					if (<attempt>5__2 < 24)
					{
						if (!saveManagerPlugin.overflowTempEquipGenerationByPlayer.TryGetValue(playerKey, out var value) || value != generation)
						{
							return false;
						}
						if (<attempt>5__2 > 0)
						{
							<>2__current = (object)new WaitForSeconds(0.5f);
							<>1__state = 2;
							return true;
						}
						goto IL_009e;
					}
					saveManagerPlugin.LogVerbose($"Delayed overflow temp equip failed after {24} attempts for item {expectedItemId}.");
					saveManagerPlugin.ClearOverflowTempEquipGenerationIfCurrent(playerKey, generation);
					return false;
					IL_009e:
					if (IsUsablePlayerForRestore(player) && player.tempFullSlot != null && !((Object)(object)player.tempFullSlot.prefab == (Object)null) && player.tempFullSlot.prefab.itemID == expectedItemId)
					{
						Character val = character;
						if ((Object)(object)val == (Object)null)
						{
							val = player.character;
						}
						CharacterItems val2 = (((Object)(object)val != (Object)null && val.refs != null) ? val.refs.items : null);
						if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val == (Object)null))
						{
							if (IsCharacterHoldingItem(val, expectedItemId))
							{
								saveManagerPlugin.TrySyncInventoryNetwork(player);
								saveManagerPlugin.LogVerbose($"Delayed overflow temp equip confirmed already held on attempt {<attempt>5__2 + 1}/{24} for item {expectedItemId}.");
								saveManagerPlugin.ClearOverflowTempEquipGenerationIfCurrent(playerKey, generation);
								return false;
							}
							bool flag = TryEquipItem(val2, player.tempFullSlot.prefab);
							bool flag2 = IsCharacterHoldingItem(val, expectedItemId);
							bool flag3 = false;
							bool flag4 = false;
							if (!flag2)
							{
								flag3 = TryEquipSlot(val2, 250);
								flag4 = IsCharacterSelectedSlot(val, 250);
								flag2 = IsCharacterHoldingItem(val, expectedItemId);
							}
							if (flag2 || flag4)
							{
								saveManagerPlugin.TrySyncInventoryNetwork(player);
								saveManagerPlugin.LogVerbose($"Delayed overflow temp equip succeeded on attempt {<attempt>5__2 + 1}/{24}. " + $"TempItem={expectedItemId} InvokeItem={flag} " + $"InvokeOverflowSlot={flag3} Holding={flag2} " + $"SelectedOverflow={flag4}");
								saveManagerPlugin.ClearOverflowTempEquipGenerationIfCurrent(playerKey, generation);
								return false;
							}
							if (<attempt>5__2 == 0 || <attempt>5__2 == 23 || (<attempt>5__2 + 1) % 6 == 0)
							{
								saveManagerPlugin.LogVerbose($"Delayed overflow temp equip retry {<attempt>5__2 + 1}/{24}. TempItem={expectedItemId} " + $"InvokeItem={flag} InvokeOverflowSlot={flag3} " + $"Holding={flag2} SelectedOverflow={flag4}");
							}
						}
					}
					<attempt>5__2++;
					goto IL_0334;
				}
			}

			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 <EnsurePendingSeedAppliedRoutine>d__251 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveManagerPlugin <>4__this;

			public string sceneName;

			private int <seed>5__2;

			private float <timeout>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!PendingSeedForLoad.HasValue || PendingSeedConsumedForLoad)
					{
						return false;
					}
					<seed>5__2 = PendingSeedForLoad.Value;
					<timeout>5__3 = 4f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<timeout>5__3 > 0f && !PendingSeedConsumedForLoad)
				{
					if (saveManagerPlugin.TryForceApplyPendingSeedToGeneration(<seed>5__2, sceneName))
					{
						return false;
					}
					<timeout>5__3 -= Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (!PendingSeedConsumedForLoad)
				{
					ManualLogSource logger = ((BaseUnityPlugin)saveManagerPlugin).Logger;
					string[] obj = new string[6]
					{
						$"Pending seed {<seed>5__2} could not be force-applied before restore. ",
						"Scene='",
						Safe(sceneName),
						"' ActiveScene='",
						null,
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[4] = ((Scene)(ref activeScene)).name;
					obj[5] = "'.";
					logger.LogWarning((object)string.Concat(obj));
				}
				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__216 : 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__216(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__216(0);
			}

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

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

			private object <>2__current;

			public SaveManagerPlugin <>4__this;

			public string fullPath;

			private <>c__DisplayClass249_0 <>8__1;

			private SaveEnvelope <envelope>5__2;

			private string <targetScene>5__3;

			private bool <needsSceneLoad>5__4;

			private int <appliedCount>5__5;

			private Player <forcedSinglePlayerTarget>5__6;

			private Segment <targetSegment>5__7;

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

			private PlayerSnapshot <playerSnapshot>5__9;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0479: Unknown result type (might be due to invalid IL or missing references)
				//IL_047e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0718: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_04af: Unknown result type (might be due to invalid IL or missing references)
				//IL_0654: Unknown result type (might be due to invalid IL or missing references)
				//IL_0685: Unknown result type (might be due to invalid IL or missing references)
				//IL_068a: Unknown result type (might be due to invalid IL or missing references)
				//IL_013a: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a0f: Unknown result type (might be due to invalid IL or missing references)
				//IL_09bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0254: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_06f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_06fb: Expected O, but got Unknown
				//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_027e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0362: Unknown result type (might be due to invalid IL or missing references)
				//IL_0367: Unknown result type (might be due to invalid IL or missing references)
				//IL_0345: Unknown result type (might be due to invalid IL or missing references)
				//IL_0329: Unknown result type (might be due to invalid IL or missing references)
				bool result;
				try
				{
					int num = <>1__state;
					SaveManagerPlugin saveManagerPlugin = <>4__this;
					Scene activeScene;
					switch (num)
					{
					default:
						result = false;
						goto end_IL_0000;
					case 0:
						<>1__state = -1;
						if (saveManagerPlugin.isLoading)
						{
							result = false;
						}
						else
						{
							saveManagerPlugin.isLoading = true;
							saveManagerPlugin.loadStartedRealtime = Time.realtimeSinceStartup;
							saveManagerPlugin.SetStatus("Loading save...", Color.cyan, 10f);
							<>1__state = -3;
							saveManagerPlugin.overflowTempEquipGenerationByPlayer.Clear();
							saveManagerPlugin.protectedGroundItemMarkers.Clear();
							saveManagerPlugin.ropeLinkRestoreSettledForCurrentLoad = false;
							saveManagerPlugin.lastRopeLinkRestoreRealtime = -1f;
							saveManagerPlugin.lastRopeLinkExpectedCount = -1;
							saveManagerPlugin.lastRopeLinkResolvedCount = -1;
							saveManagerPlugin.lastGroundRestorePhase = string.Empty;
							saveManagerPlugin.lastGroundRestoreMatchedAllForCurrentPhase = false;
							saveManagerPlugin.lastGroundRestoreHadFailuresForCurrentPhase = false;
							saveManagerPlugin.lateWorldReconcileToken++;
							if (saveManagerPlugin.lateWorldReconcileCoroutine != null)
							{
								((MonoBehaviour)saveManagerPlugin).StopCoroutine(saveManagerPlugin.lateWorldReconcileCoroutine);
								saveManagerPlugin.lateWorldReconcileCoroutine = null;
							}
							if (saveManagerPlugin.deferredGroundRestoreCoroutine != null)
							{
								((MonoBehaviour)saveManagerPlugin).StopCoroutine(saveManagerPlugin.deferredGroundRestoreCoroutine);
								saveManagerPlugin.deferredGroundRestoreCoroutine = null;
							}
							string[] obj = new string[6]
							{
								"LoadSaveRoutine start. Path='",
								Safe(fullPath),
								"' ActiveScene='",
								null,
								null,
								null
							};
							activeScene = SceneManager.GetActiveScene();
							obj[3] = ((Scene)(ref activeScene)).name;
							obj[4] = "' ";
							obj[5] = $"InRoom={PhotonNetwork.InRoom} IsHost={PhotonNetwork.IsMasterClient}";
							saveManagerPlugin.LogVerbose(string.Concat(obj));
							if (!TryReadSaveEnvelope(fullPath, out <envelope>5__2, out var reason))
							{
								saveManagerPlugin.SetStatus("Incompatible save: " + reason, Color.yellow, 6f);
								saveManagerPlugin.LogVerbose("Load rejected by TryReadSaveEnvelope. Reason='" + Safe(reason) + "'");
								result = false;
								break;
							}
							saveManagerPlugin.LogVerbose("Loaded envelope from disk. " + DescribeEnvelope(<envelope>5__2));
							if (<envelope>5__2.players != null)
							{
								for (int i = 0; i < <envelope>5__2.players.Count; i++)
								{
									saveManagerPlugin.LogVerbose("Envelope player: " + DescribePlayerSnapshot(<envelope>5__2.players[i]));
								}
							}
							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;
							}
							saveManagerPlugin.ApplySavedDailyLevelIndexOverride(<envelope>5__2.metadata);
							<targetScene>5__3 = ResolveTargetScene(<envelope>5__2.metadata);
							bool flag = SaveNeedsNonAirportScene(<envelope>5__2.metadata);
							string text = $"Load scene resolve. TargetScene='{Safe(<targetScene>5__3)}' SaveNeedsRunScene={flag} ";
							activeScene = SceneManager.GetActiveScene();
							saveManagerPlugin.LogVerbose(text + "CurrentScene='" + ((Scene)(ref activeScene)).name + "'");
							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))
							{
								activeScene = SceneManager.GetActiveScene();
								num2 = ((!string.Equals(((Scene)(ref activeScene)).name, <targetScene>5__3, StringComparison.OrdinalIgnoreCase)) ? 1 : 0);
							}
							else
							{
								num2 = 0;
							}
							<needsSceneLoad>5__4 = (byte)num2 != 0;
							saveManagerPlugin.LogVerbose($"Load scene decision. NeedsSceneLoad={<needsSceneLoad>5__4}");
							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 (!<needsSceneLoad>5__4)
							{
								Ascents.currentAscent = <envelope>5__2.metadata.ascent;
								saveManagerPlugin.LogVerbose($"Scene load skipped. Applied ascent={<envelope>5__2.metadata.ascent} on current scene.");
								goto IL_04ff;
							}
							saveManagerPlugin.LogVerbose($"Starting scene load to '{<targetScene>5__3}' with ascent={<envelope>5__2.metadata.ascent}.");
							<>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;
						object arg = saveManagerPlugin.lastSceneLoadSucceeded;
						activeScene = SceneManager.GetActiveScene();
						saveManagerPlugin.LogVerbose($"Scene load routine returned. Success={arg} ActiveScene='{((Scene)(ref activeScene)).name}'");
						if (!saveManagerPlugin.lastSceneLoadSucceeded)
						{
							saveManagerPlugin.SetStatus("Failed to load scene '" + <targetScene>5__3 + "'.", Color.red, 6f);
							result = false;
							break;
						}
						goto IL_04ff;
					}
					case 2:
						<>1__state = -3;
						goto IL_0571;
					case 3:
						<>1__state = -3;
						goto IL_05ad;
					case 4:
					{
						<>1__state = -3;
						int num3 = saveManagerPlugin.CountMatchedPlayers(<envelope>5__2.players);
						saveManagerPlugin.LogVerbose($"Player wait completed. MatchedPlayers={num3}/{<envelope>5__2.players.Count}");
						if (num3 <= 0)
						{
							saveManagerPlugin.SetStatus("No matching players were found for this save.", Color.yellow, 6f);
							result = false;
							break;
						}
						if (!MapHandler.Exists)
						{
							goto IL_072c;
						}
						<targetSegment>5__7 = ClampSegment(<envelope>5__2.metadata.currentSegment);
						MapHandler val2 = Object.FindFirstObjectByType<MapHandler>();
						Segment val3 = (Segment)(((Object)(object)val2 != (Object)null) ? ((int)val2.GetCurrentSegment()) : 0);
						saveManagerPlugin.LogVerbose($"Map segment before load restore. Current={val3} Target={<targetSegment>5__7}");
						if ((int)<targetSegment>5__7 == 0 || <targetSegment>5__7 == val3)
						{
							goto IL_072c;
						}
						MapHandler.JumpToSegment(<targetSegment>5__7);
						<>2__current = (object)new WaitForSeconds(0.75f);
						<>1__state = 5;
						result = true;
						goto end_IL_0000;
					}
					case 5:
						<>1__state = -3;
						saveManagerPlugin.LogVerbose($"Map segment jump applied to {<targetSegment>5__7}.");
						goto IL_072c;
					case 6:
						<>1__state = -3;
						saveManagerPlugin.LogVerbose("Completed immediate world-interactable restore.");
						<appliedCount>5__5 = 0;
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)$"Applying {<envelope>5__2.players.Count} player snapshot(s) from '{Path.GetFileName(fullPath)}'.");
						<forcedSinglePlayerTarget>5__6 = ((<envelope>5__2.players.Count == 1) ? FindPrimaryLocalPlayer() : null);
						if ((Object)(object)<forcedSinglePlayerTarget>5__6 != (Object)null)
						{
							((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)"Single-player load detected: forcing restore target to the current local player.");
						}
						<>7__wrap7 = <envelope>5__2.players.GetEnumerator();
						<>1__state = -4;
						goto IL_098c;
					case 7:
						{
							<>1__state = -4;
							if (<>8__1.restored)
							{
								<appliedCount>5__5++;
							}
							else
							{
								((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)$"Player snapshot restore failed for '{<playerSnapshot>5__9.playerName}' (Actor: {<playerSnapshot>5__9.actorNumber}).");
							}
							<>8__1 = null;
							<playerSnapshot>5__9 = null;
							goto IL_098c;
						}
						IL_04ff:
						if (!<needsSceneLoad>5__4 || !PendingSeedForLoad.HasValue || PendingSeedConsumedForLoad)
						{
							goto IL_0571;
						}
						saveManagerPlugin.LogVerbose($"Pending seed {PendingSeedForLoad.Value} was not consumed during scene load; " + "attempting direct generator seed apply.");
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.EnsurePendingSeedAppliedRoutine(<targetScene>5__3));
						<>1__state = 2;
						result = true;
						goto end_IL_0000;
						IL_05ad:
						saveManagerPlugin.LogVerbose($"Waiting for players. SnapshotPlayers={<envelope>5__2.players.Count}");
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.WaitForPlayersRoutine(<envelope>5__2.players, 20f));
						<>1__state = 4;
						result = true;
						goto end_IL_0000;
						IL_072c:
						saveManagerPlugin.LogVerbose("Starting world-interactable restore.");
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreWorldInteractablesRoutine(<envelope>5__2));
						<>1__state = 6;
						result = true;
						goto end_IL_0000;
						IL_0571:
						if (!<needsSceneLoad>5__4)
						{
							goto IL_05ad;
						}
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.WaitForLoadedSceneWorldReadyRoutine(<targetScene>5__3, <envelope>5__2));
						<>1__state = 3;
						result = true;
						goto end_IL_0000;
						IL_098c:
						while (true)
						{
							if (<>7__wrap7.MoveNext())
							{
								<playerSnapshot>5__9 = <>7__wrap7.Current;
								<>8__1 = new <>c__DisplayClass249_0();
								Player val = <forcedSinglePlayerTarget>5__6 ?? saveManagerPlugin.FindPlayer(<playerSnapshot>5__9);
								string arg2 = (((Object)(object)val != (Object)null) ? Safe(((Object)val).name) : "-");
								saveManagerPlugin.LogVerbose($"Player restore target resolve. Snapshot='{Safe(<playerSnapshot>5__9?.playerName)}' Actor={<playerSnapshot>5__9?.actorNumber ?? (-1)} Target='{arg2}'");
								if ((Object)(object)val == (Object)null)
								{
									((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)$"Could not find player for snapshot '{<playerSnapshot>5__9.playerName}' (Actor: {<playerSnapshot>5__9.actorNumber})");
									continue;
								}
								<>8__1.restored = false;
								<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.ApplyPlayerSnapshotRoutine(val, <playerSnapshot>5__9, delegate(bool success)
								{
									<>8__1.restored = success;
								}));
								<>1__state = 7;
								result = true;
							}
							else
							{
								<>m__Finally2();
								<>7__wrap7 = default(List<PlayerSnapshot>.Enumerator);
								if (<appliedCount>5__5 <= 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__5}/{<envelope>5__2.players.Count} players).", Color.green, 4f);
								saveManagerPlugin.LogVerbose($"Load completed. AppliedPlayers={<appliedCount>5__5}/{<envelope>5__2.players.Count}");
								<envelope>5__2 = null;
								<targetScene>5__3 = null;
								<forcedSinglePlayerTarget>5__6 = null;
								<>m__Finally1();
								result = false;
							}
							goto end_IL_0000;
						}
						break;
					}
					<>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;
				ClearForcedDailyLevelIndexForLoad();
				ClearPendingSeedForLoad();
				saveManagerPlugin.isLoading = false;
				saveManagerPlugin.loadStartedRealtime = -1f;
				saveManagerPlugin.RefreshSaveFileList();
			}

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

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

		[CompilerGenerated]
		private sealed class <LoadSceneRoutine>d__250 : 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 float <nextProgressLogAt>5__4;

			private bool <triedEmergencySceneFallback>5__5;

			private AsyncOperation <operation>5__6;

			private float <fallbackTimeout>5__7;

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

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

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

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

			private bool MoveNext()
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Expected O, but got Unknown
				//IL_021f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0224: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b5: 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;
					saveManagerPlugin.LogVerbose($"LoadSceneRoutine start. Scene='{sceneName}' Ascent={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;
					bool flag = saveManagerPlugin.TryBeginIslandLoadFromAirport(sceneName, ascent);
					if (flag)
					{
						<usedLoadingScreen>5__2 = true;
						saveManagerPlugin.LogVerbose("LoadSceneRoutine started via AirportCheckInKiosk.BeginIslandLoadRPC.");
					}
					else
					{
						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;
								saveManagerPlugin.LogVerbose("LoadSceneRoutine using LoadingScreenHandler process.");
							}
						}
						catch (Exception ex2)
						{
							((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("LoadingScreenHandler load failed, using fallback load: " + ex2.Message));
						}
					}
					if (!<usedLoadingScreen>5__2 && !flag)
					{
						saveManagerPlugin.LogVerbose("LoadSceneRoutine falling back to SceneManager.LoadSceneAsync.");
						<operation>5__6 = SceneManager.LoadSceneAsync(sceneName);
						if (<operation>5__6 == null)
						{
							((BaseUnityPlugin)saveManagerPlugin).Logger.LogError((object)("Could not start fallback scene load for '" + sceneName + "'."));
							return false;
						}
						<fallbackTimeout>5__7 = 45f;
						goto IL_01b0;
					}
					goto IL_01fc;
				}
				case 1:
					<>1__state = -1;
					goto IL_01b0;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_01b0:
					if (!<operation>5__6.isDone && <fallbackTimeout>5__7 > 0f)
					{
						<fallbackTimeout>5__7 -= Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					saveManagerPlugin.LogVerbose($"Fallback scene load loop finished. Done={<operation>5__6.isDone} RemainingTimeout={<fallbackTimeout>5__7:0.##}s");
					<operation>5__6 = null;
					goto IL_01fc;
					IL_01fc:
					<timeout>5__3 = 45f;
					<nextProgressLogAt>5__4 = <timeout>5__3;
					<triedEmergencySceneFallback>5__5 = false;
					break;
				}
				Scene activeScene;
				if (<timeout>5__3 > 0f)
				{
					activeScene = SceneManager.GetActiveScene();
					string name = ((Scene)(ref activeScene)).name;
					bool flag2 = string.Equals(name, sceneName, StringComparison.OrdinalIgnoreCase);
					bool flag3 = !<usedLoadingScreen>5__2 || !LoadingScreenHandler.loading;
					if (flag2 && flag3)
					{
						saveManagerPlugin.lastSceneLoadSucceeded = true;
						saveManagerPlugin.LogVerbose("LoadSceneRoutine success. ActiveScene='" + name + "'");
						return false;
					}
					if ((!<triedEmergencySceneFallback>5__5 & <usedLoadingScreen>5__2) && string.Equals(name, "Airport", StringComparison.OrdinalIgnoreCase) && <timeout>5__3 < 35f)
					{
						<triedEmergencySceneFallback>5__5 = true;
						if (SceneManager.LoadSceneAsync(sceneName) != null)
						{
							<usedLoadingScreen>5__2 = false;
							saveManagerPlugin.LogVerbose("LoadSceneRoutine emergency fallback started SceneManager.LoadSceneAsync.");
						}
						else
						{
							saveManagerPlugin.LogVerbose("LoadSceneRoutine emergency fallback could not start SceneManager.LoadSceneAsync.");
						}
					}
					if (saveManagerPlugin.IsVerboseLoggingEnabled() && <timeout>5__3 <= <nextProgressLogAt>5__4 - 1f)
					{
						<nextProgressLogAt>5__4 = <timeout>5__3;
						saveManagerPlugin.LogVerbose($"LoadSceneRoutine progress. Remaining={<timeout>5__3:0.##}s ActiveScene='{name}' " + $"SceneMatches={flag2} LoadingScreenBusy={<usedLoadingScreen>5__2 && LoadingScreenHandler.loading}");
					}
					<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."));
				TryForceClearLoadingScreenBusyFlag();
				activeScene = SceneManager.GetActiveScene();
				saveManagerPlugin.LogVerbose("LoadSceneRoutine timeout. ActiveScene='" + ((Scene)(ref activeScene)).name + "'");
				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 <RestoreGroundItemsDeferredRoutine>d__307 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public List<GroundItemSnapshot> snapshots;

			public string label;

			public SaveManagerPlugin <>4__this;

			private string <phase>5__2;

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

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

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

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

			private bool MoveNext()
			{
				bool result;
				try
				{
					int num = <>1__state;
					SaveManagerPlugin saveManagerPlugin = <>4__this;
					switch (num)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<>1__state = -3;
						if (snapshots == null || snapshots.Count == 0)
						{
							result = false;
							<>m__Finally1();
							break;
						}
						<phase>5__2 = (string.IsNullOrWhiteSpace(label) ? "deferred" : label.Trim());
						<>2__current = null;
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						saveManagerPlugin.LogVerbose($"Deferred ground restore '{<phase>5__2}' starting. SnapshotCount={snapshots.Count}");
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreGroundItemsRoutine(snapshots, <phase>5__2));
						<>1__state = 2;
						result = true;
						break;
					case 2:
						<>1__state = -3;
						<phase>5__2 = null;
						<>m__Finally1();
						result = false;
						break;
					}
				}
				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;
				<>4__this.deferredGroundRestoreCoroutine = null;
			}

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

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

			private object <>2__current;

			public List<GroundItemSnapshot> itemSnapshots;

			public string phaseLabel;

			public SaveManagerPlugin <>4__this;

			private string <phase>5__2;

			private bool <allowExtraCleanup>5__3;

			private bool <allowSpawning>5__4;

			private List<Item> <candidates>5__5;

			private int <matchedCount>5__6;

			private int <spawnedCount>5__7;

			private int <failedSpawnCount>5__8;

			private int <removedCount>5__9;

			private int <preservedCount>5__10;

			private int <errorCount>5__11;

			private int <i>5__12;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<phase>5__2 = null;
				<candidates>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				Item val3;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					if (itemSnapshots == null)
					{
						return false;
					}
					<phase>5__2 = (string.IsNullOrWhiteSpace(phaseLabel) ? "ground" : phaseLabel.Trim());
					<allowExtraCleanup>5__3 = !<phase>5__2.StartsWith("late-", StringComparison.OrdinalIgnoreCase);
					<allowSpawning>5__4 = <phase>5__2.StartsWith("late-", StringComparison.OrdinalIgnoreCase);
					Item[] source = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
					<candidates>5__5 = new List<Item>(source.Where(IsGroundItemCandidate));
					int count = <candidates>5__5.Count;
					<matchedCount>5__6 = 0;
					<spawnedCount>5__7 = 0;
					<failedSpawnCount>5__8 = 0;
					<removedCount>5__9 = 0;
					<preservedCount>5__10 = 0;
					<errorCount>5__11 = 0;
					saveManagerPlugin.PruneExpiredProtectedGroundMarkers();
					saveManagerPlugin.LogVerbose($"RestoreGroundItems[{<phase>5__2}] start. Snapshots={itemSnapshots.Count} CandidateGroundItems={count}");
					<i>5__12 = 0;
					goto IL_02f5;
				}
				case 1:
					<>1__state = -1;
					goto IL_02e3;
				case 2:
					{
						<>1__state = -1;
						goto IL_047f;
					}
					IL_02f5:
					if (<i>5__12 < itemSnapshots.Count)
					{
						try
						{
							GroundItemSnapshot groundItemSnapshot = itemSnapshots[<i>5__12];
							if (groundItemSnapshot != null && groundItemSnapshot.itemId != ushort.MaxValue)
							{
								Item val = FindGroundItemForSnapshot(groundItemSnapshot, <candidates>5__5, 16f);
								if ((Object)(object)val != (Object)null)
								{
									<candidates>5__5.Remove(val);
									ApplyGroundItemSnapshot(val, groundItemSnapshot);
									<matchedCount>5__6++;
								}
								else if (<allowSpawning>5__4)
								{
									Item val2 = saveManagerPlugin.TrySpawnGroundItem(groundItemSnapshot);
									if ((Object)(object)val2 != (Object)null)
									{
										ApplyGroundItemSnapshot(val2, groundItemSnapshot);
										<spawnedCount>5__7++;
									}
									else
									{
										<failedSpawnCount>5__8++;
									}
									goto IL_023c;
								}
							}
						}
						catch (Exception ex)
						{
							<errorCount>5__11++;
							((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)$"RestoreGroundItems[{<phase>5__2}] failed at snapshot index {<i>5__12}: {ex.Message}");
							goto IL_023c;
						}
						goto IL_02e3;
					}
					if (<allowExtraCleanup>5__3)
					{
						<i>5__12 = 0;
						goto IL_0491;
					}
					saveManagerPlugin.LogVerbose($"RestoreGroundItems[{<phase>5__2}] skipped extra cleanup pass; preserving {<candidates>5__5.Count} unmatched candidates.");
					break;
					IL_02e3:
					<i>5__12++;
					goto IL_02f5;
					IL_0491:
					if (<i>5__12 >= <candidates>5__5.Count)
					{
						break;
					}
					val3 = <candidates>5__5[<i>5__12];
					if (!((Object)(object)val3 == (Object)null))
					{
						if (saveManagerPlugin.ShouldPreserveGroundItemDuringCleanup(val3))
						{
							<preservedCount>5__10++;
						}
						else
						{
							try
							{
								if (!PhotonNetwork.InRoom)
								{
									goto IL_03ab;
								}
								PhotonView photonView = GetPhotonView((Component)(object)val3);
								if (!((Object)(object)photonView != (Object)null) || photonView.ViewID <= 0)
								{
									goto IL_03ab;
								}
								PhotonNetwork.Destroy(((Component)val3).gameObject);
								<removedCount>5__9++;
								goto end_IL_0364;
								IL_03ab:
								Object.Destroy((Object)(object)((Component)val3).gameObject);
								<removedCount>5__9++;
								goto IL_03fd;
								end_IL_0364:;
							}
							catch (Exception ex2)
							{
								<errorCount>5__11++;
								((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("Failed to remove extra ground item: " + ex2.Message));
								goto IL_03fd;
							}
						}
					}
					goto IL_047f;
					IL_03fd:
					if ((<i>5__12 + 1) % 20 == 0)
					{
						saveManagerPlugin.LogVerbose($"RestoreGroundItems[{<phase>5__2}] cleanup progress {<i>5__12 + 1}/{<candidates>5__5.Count} removed={<removedCount>5__9} errors={<errorCount>5__11}");
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					goto IL_047f;
					IL_047f:
					<i>5__12++;
					goto IL_0491;
					IL_023c:
					if ((<i>5__12 + 1) % 20 == 0)
					{
						saveManagerPlugin.LogVerbose($"RestoreGroundItems[{<phase>5__2}] progress {<i>5__12 + 1}/{itemSnapshots.Count} " + $"matched={<matchedCount>5__6} spawned={<spawnedCount>5__7} spawnFailed={<failedSpawnCount>5__8} errors={<errorCount>5__11}");
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_02e3;
				}
				saveManagerPlugin.LogVerbose($"RestoreGroundItems[{<phase>5__2}] finished. Matched={<matchedCount>5__6} Spawned={<spawnedCount>5__7} " + $"SpawnFailed={<failedSpawnCount>5__8} RemovedExtras={<removedCount>5__9} PreservedExtras={<preservedCount>5__10} " + $"Errors={<errorCount>5__11} UnmatchedCandidates={<candidates>5__5.Count}");
				int num2 = <matchedCount>5__6 + <spawnedCount>5__7;
				saveManagerPlugin.lastGroundRestorePhase = <phase>5__2;
				saveManagerPlugin.lastGroundRestoreMatchedAllForCurrentPhase = num2 >= itemSnapshots.Count;
				saveManagerPlugin.lastGroundRestoreHadFailuresForCurrentPhase = <failedSpawnCount>5__8 > 0 || <errorCount>5__11 > 0;
				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__305 : 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__305(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Expected O, but got Unknown
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: 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.LogVerbose($"RestoreWorldInteractables start. Campfires={envelope.campfires?.Count ?? 0} " + $"Containers={envelope.containerStates?.Count ?? 0} GroundItems={envelope.groundItems?.Count ?? 0} " + $"WorldObjects={envelope.worldObjects?.Count ?? 0}");
					saveManagerPlugin.RestoreCampfires(envelope.campfires);
					saveManagerPlugin.RestoreContainerStates(envelope.containerStates, envelope.luggageStates);
					saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					saveManagerPlugin.LogVerbose("RestoreWorldInteractables pass 1 complete.");
					<>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);
					saveManagerPlugin.LogVerbose("RestoreWorldInteractables pass 2 complete.");
					<>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.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
					saveManagerPlugin.LogVerbose("RestoreWorldInteractables pass 3 complete.");
					if ((Object)(object)saveManagerPlugin != (Object)null && (Object)(object)((Component)saveManagerPlugin).gameObject != (Object)null && ((Component)saveManagerPlugin).gameObject.activeInHierarchy)
					{
						if (saveManagerPlugin.deferredGroundRestoreCoroutine != null)
						{
							((MonoBehaviour)saveManagerPlugin).StopCoroutine(saveManagerPlugin.deferredGroundRestoreCoroutine);
						}
						saveManagerPlugin.deferredGroundRestoreCoroutine = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreGroundItemsDeferredRoutine(envelope.groundItems, "main"));
					}
					if ((Object)(object)saveManagerPlugin != (Object)null && (Object)(object)((Component)saveManagerPlugin).gameObject != (Object)null && ((Component)saveManagerPlugin).gameObject.activeInHierarchy)
					{
						if (saveManagerPlugin.lateWorldReconcileCoroutine != null)
						{
							((MonoBehaviour)saveManagerPlugin).StopCoroutine(saveManagerPlugin.lateWorldReconcileCoroutine);
						}
						int reconcileToken = ++saveManagerPlugin.lateWorldReconcileToken;
						saveManagerPlugin.lateWorldReconcileCoroutine = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreWorldLatePassesRoutine(envelope, reconcileToken));
						saveManagerPlugin.LogVerbose("RestoreWorldInteractables queued late passes.");
					}
					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 <RestoreWorldLatePassesRoutine>d__306 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SaveEnvelope envelope;

			public int reconcileToken;

			public SaveManagerPlugin <>4__this;

			private float[] <latePassDelays>5__2;

			private bool <groundSettled>5__3;

			private int <i>5__4;

			private bool <runGroundReconcile>5__5;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Expected O, but got Unknown
				bool result;
				try
				{
					int num = <>1__state;
					SaveManagerPlugin saveManagerPlugin = <>4__this;
					bool flag;
					bool num2;
					bool ropeLinkRestoreSettledForCurrentLoad;
					switch (num)
					{
					default:
						result = false;
						goto end_IL_0000;
					case 0:
						<>1__state = -1;
						if (envelope != null && reconcileToken == saveManagerPlugin.lateWorldReconcileToken)
						{
							<latePassDelays>5__2 = new float[3] { 2.6f, 2f, 2f };
							<>1__state = -3;
							<groundSettled>5__3 = false;
							<i>5__4 = 0;
							goto IL_02f5;
						}
						result = false;
						goto end_IL_0000;
					case 1:
						<>1__state = -3;
						if (reconcileToken != saveManagerPlugin.lateWorldReconcileToken)
						{
							result = false;
							break;
						}
						saveManagerPlugin.LogVerbose($"Starting late world reconcile pass {<i>5__4 + 1}/{<latePassDelays>5__2.Length} after delay={<latePassDelays>5__2[<i>5__4]:0.##}s.");
						<runGroundReconcile>5__5 = <i>5__4 == 0 || !<groundSettled>5__3;
						if (!<runGroundReconcile>5__5)
						{
							goto IL_01aa;
						}
						saveManagerPlugin.RestoreCampfires(envelope.campfires);
						saveManagerPlugin.RestoreContainerStates(envelope.containerStates, envelope.luggageStates);
						<>2__current = ((MonoBehaviour)saveManagerPlugin).StartCoroutine(saveManagerPlugin.RestoreGroundItemsRoutine(envelope.groundItems, $"late-{<i>5__4 + 1}"));
						<>1__state = 2;
						result = true;
						goto end_IL_0000;
					case 2:
						{
							<>1__state = -3;
							goto IL_01aa;
						}
						IL_02f5:
						if (<i>5__4 >= <latePassDelays>5__2.Length)
						{
							goto IL_0308;
						}
						if (reconcileToken != saveManagerPlugin.lateWorldReconcileToken)
						{
							result = false;
							break;
						}
						<>2__current = (object)new WaitForSeconds(<latePassDelays>5__2[<i>5__4]);
						<>1__state = 1;
						result = true;
						goto end_IL_0000;
						IL_01aa:
						saveManagerPlugin.RestoreWorldObjects(envelope.worldObjects, envelope.formatVersion);
						((BaseUnityPlugin)saveManagerPlugin).Logger.LogInfo((object)$"Completed late world reconcile pass {<i>5__4 + 1}/{<latePassDelays>5__2.Length}.");
						flag = !string.IsNullOrWhiteSpace(saveManagerPlugin.lastGroundRestorePhase) && saveManagerPlugin.lastGroundRestorePhase.StartsWith("late-", StringComparison.OrdinalIgnoreCase);
						if (<runGroundReconcile>5__5)
						{
							<groundSettled>5__3 = flag && saveManagerPlugin.lastGroundRestoreMatchedAllForCurrentPhase && !saveManagerPlugin.lastGroundRestoreHadFailuresForCurrentPhase;
						}
						num2 = <groundSettled>5__3 || (!<runGroundReconcile>5__5 && <i>5__4 > 0);
						ropeLinkRestoreSettledForCurrentLoad = saveManagerPlugin.ropeLinkRestoreSettledForCurrentLoad;
						if (!(num2 && ropeLinkRestoreSettledForCurrentLoad))
						{
							if (!<runGroundReconcile>5__5 && !ropeLinkRestoreSettledForCurrentLoad)
							{
								saveManagerPlugin.LogVerbose($"Late pass {<i>5__4 + 1} kept as rope-only retry. RopeSettled={ropeLinkRestoreSettledForCurrentLoad}");
							}
							else if (<runGroundReconcile>5__5)
							{
								saveManagerPlugin.LogVerbose($"Late pass {<i>5__4 + 1} status. GroundSettled={<groundSettled>5__3} " + $"RopeSettled={ropeLinkRestoreSettledForCurrentLoad}");
							}
							<i>5__4++;
							goto IL_02f5;
						}
						goto IL_0308;
						IL_0308:
						<>m__Finally1();
						result = false;
						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;
				if (reconcileToken == saveManagerPlugin.lateWorldReconcileToken)
				{
					saveManagerPlugin.lateWorldReconcileCoroutine = null;
				}
			}

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

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

			private object <>2__current;

			public Character character;

			public Vector3 targetPosition;

			public Vector3 targetEulerRotation;

			private float <endRealtime>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)character == (Object)null)
					{
						return false;
					}
					<endRealtime>5__2 = Time.realtimeSinceStartup + 0.45f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (Time.realtimeSinceStartup < <endRealtime>5__2)
				{
					if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
					{
						return false;
					}
					ResetCharacterLocomotionForLoad(character);
					ApplyCharacterTransformSnapshot(character, targetPosition, targetEulerRotation);
					Rigidbody val = ((character.refs != null && (Object)(object)character.refs.hip != (Object)null) ? character.refs.hip.Rig : null);
					if ((Object)(object)val != (Object)null)
					{
						try
						{
							val.position = targetPosition;
							val.rotation = Quaternion.Euler(targetEulerRotation);
							val.linearVelocity = Vector3.zero;
							val.angularVelocity = Vector3.zero;
						}
						catch
						{
						}
					}
					<>2__current = null;
					<>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();
			}
		}

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

			private object <>2__current;

			public string sceneName;

			public SaveEnvelope envelope;

			public SaveManagerPlugin <>4__this;

			private int <minCampfires>5__2;

			private int <minLuggage>5__3;

			private bool <requireSeedConsumption>5__4;

			private float <timeout>5__5;

			private float <nextProgressLogAt>5__6;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: 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;
					if (string.IsNullOrWhiteSpace(sceneName))
					{
						return false;
					}
					int valueOrDefault = (envelope?.campfires?.Count).GetValueOrDefault();
					int valueOrDefault2 = (envelope?.luggageStates?.Count).GetValueOrDefault();
					<minCampfires>5__2 = ((valueOrDefault > 0) ? Mathf.Clamp(valueOrDefault / 2, 1, valueOrDefault) : 0);
					<minLuggage>5__3 = ((valueOrDefault2 > 0) ? Mathf.Clamp(valueOrDefault2 / 3, 4, valueOrDefault2) : 0);
					<requireSeedConsumption>5__4 = PendingSeedForLoad.HasValue;
					<timeout>5__5 = 20f;
					<nextProgressLogAt>5__6 = <timeout>5__5;
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<timeout>5__5 > 0f)
				{
					Scene activeScene = SceneManager.GetActiveScene();
					string name = ((Scene)(ref activeScene)).name;
					bool flag = string.Equals(name, sceneName, StringComparison.OrdinalIgnoreCase);
					bool flag2 = MapHandler.Exists && (Object)(object)Object.FindFirstObjectByType<MapHandler>() != (Object)null;
					int num2 = SaveManagerPlugin.CountSceneComponents<Campfire>(sceneName);
					int num3 = SaveManagerPlugin.CountSceneComponents<Luggage>(sceneName);
					bool flag3 = <minCampfires>5__2 <= 0 || num2 >= <minCampfires>5__2;
					bool flag4 = <minLuggage>5__3 <= 0 || num3 >= <minLuggage>5__3;
					bool flag5 = !<requireSeedConsumption>5__4 || PendingSeedConsumedForLoad || PendingSeedStagedForLoad;
					if (!flag5 && PendingSeedForLoad.HasValue && !PendingSeedStagedForLoad)
					{
						saveManagerPlugin.TryForceApplyPendingSeedToGeneration(PendingSeedForLoad.Value, sceneName);
					}
					if (flag && flag2 && flag3 && flag4 && flag5)
					{
						saveManagerPlugin.LogVerbose($"Loaded scene world ready. Scene='{sceneName}' Campfires={num2}/{Math.Max(<minCampfires>5__2, 0)} " + $"Luggage={num3}/{Math.Max(<minLuggage>5__3, 0)} SeedReady={flag5}");
						return false;
					}
					if (saveManagerPlugin.IsVerboseLoggingEnabled() && <timeout>5__5 <= <nextProgressLogAt>5__6 - 1f)
					{
						<nextProgressLogAt>5__6 = <timeout>5__5;
						saveManagerPlugin.LogVerbose($"WaitForLoadedSceneWorldReady progress. Remaining={<timeout>5__5:0.##}s ActiveScene='{name}' " + $"SceneMatches={flag} MapHandlerReady={flag2} " + $"Campfires={num2}/{Math.Max(<minCampfires>5__2, 0)} Luggage={num3}/{Math.Max(<minLuggage>5__3, 0)} " + string.Format("SeedReady={0} PendingSeed={1}", flag5, PendingSeedForLoad.HasValue ? PendingSeedForLoad.Value.ToString(CultureInfo.InvariantCulture) : "-"));
					}
					<timeout>5__5 -= Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				((BaseUnityPlugin)saveManagerPlugin).Logger.LogWarning((object)("Timed out waiting for loaded scene readiness. Scene='" + Safe(sceneName) + "' " + $"Campfires={SaveManagerPlugin.CountSceneComponents<Campfire>(sceneName)} Luggage={SaveManagerPlugin.CountSceneComponents<Luggage>(sceneName)} " + $"SeedReady={!PendingSeedForLoad.HasValue || PendingSeedConsumedForLoad || PendingSeedStagedForLoad}."));
				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__256 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public float timeoutSeconds;

			public SaveManagerPlugin <>4__this;

			public List<PlayerSnapshot> players;

			private float <timeout>5__2;

			private float <nextProgressLogAt>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ec: Expected O, but got Unknown
				int num = <>1__state;
				SaveManagerPlugin saveManagerPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeout>5__2 = Mathf.Max(1f, timeoutSeconds);
					<nextProgressLogAt>5__3 = <timeout>5__2;
					saveManagerPlugin.LogVerbose($"WaitForPlayersRoutine start. Timeout={<timeout>5__2:0.##}s SnapshotPlayers={players?.Count ?? 0}");
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<timeout>5__2 > 0f)
				{
					int num2 = 0;
					bool flag = false;
					if (players != null && players.Count > 0)
					{
						for (int i = 0; i < players.Count; i++)
						{
							if ((Object)(object)saveManagerPlugin.FindPlayerStrict(players[i]) != (Object)null)
							{
								num2++;
							}
						}
						if (num2 > 0)
						{
							return false;
						}
						if (players.Count == 1 && (Object)(object)FindPrimaryLocalPlayer() != (Object)null)
						{
							saveManagerPlugin.LogVerbose("WaitForPlayersRoutine finished via single-player local fallback.");
							return false;
						}
						flag = players.Count == 1 && (Object)(object)FindPrimaryLocalPlayer() != (Object)null;
					}
					else if ((Object)(object)FindPrimaryLocalPlayer() != (Object)null)
					{
						saveManagerPlugin.LogVerbose("WaitForPlayersRoutine finished via local-player fallback with no snapshot player list.");
						return false;
					}
					if (saveManagerPlugin.IsVerboseLoggingEnabled() && <timeout>5__2 <= <nextProgressLogAt>5__3 - 1f)
					{
						<nextProgressLogAt>5__3 = <timeout>5__2;
						int num3 = Object.FindObjectsByType<Player>((FindObjectsSortMode)0).Count(IsUsablePlayerForRestore);
						saveManagerPlugin.LogVerbose($"WaitForPlayers progress. Remaining={<timeout>5__2:0.##}s StrictMatched={num2} " + $"LiveUsablePlayers={num3} SinglePlayerFallbackReady={flag}");
					}
					<timeout>5__2 -= Time.deltaTime;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				saveManagerPlugin.LogVerbose("WaitForPlayersRoutine timed out.");
				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.1";

		private const string SaveFilePattern = "*.json";

		private const int UiWindowId = 129193;

		private const string PauseMenuButtonObjectName = "PeakSaveManagerButton";

		private const float PendingSeedLifetimeSeconds = 90f;

		private const byte OverflowTempSlotId = 250;

		private const float ProtectedOverflowDropLifetimeSeconds = 45f;

		private const float ProtectedOverflowDropRadiusSquared = 4f;

		private const float PitonNearPlayerDistanceThresholdSqr = 122500f;

		private const string WorldObjectKindCloudFungus = "CloudFungus";

		private const string WorldObjectKindBounceFungus = "BounceFungus";

		private const string WorldObjectKindShelfFungus = "ShelfFungus";

		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 MethodInfo LevelGenerationGenerateMethod = AccessTools.Method(typeof(LevelGeneration), "Generate", (Type[])null, (Type[])null);

		private static readonly MethodInfo LevelGenerationClearMethod = AccessTools.Method(typeof(LevelGeneration), "Clear", (Type[])null, (Type[])null);

		private static readonly MethodInfo LevelGenerationRandomizeBiomeVariantsMethod = AccessTools.Method(typeof(LevelGeneration), "RandomizeBiomeVariants", (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 = GetPropertySetterOrNull(typeof(RespawnChest), "IsSpent");

		private static readonly MethodInfo RespawnChestSetRevivedPlayersMethod = GetPropertySetterOrNull(typeof(RespawnChest), "HasRevivedPlayers") ?? GetPropertySetterOrNull(typeof(RespawnChest), "HasRevived");

		private static readonly PropertyInfo RespawnChestIsSpentProperty = GetPropertyOrNull(typeof(RespawnChest), "IsSpent");

		private static readonly PropertyInfo RespawnChestHasRevivedPlayersProperty = GetPropertyOrNull(typeof(RespawnChest), "HasRevivedPlayers") ?? GetPropertyOrNull(typeof(RespawnChest), "HasRevived");

		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 MethodInfo CharacterDataSetSkeletonMethod = AccessTools.Method(typeof(CharacterData), "SetSkeleton", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo CharacterDataSyncSkeletonMethod = AccessTools.Method(typeof(CharacterData), "RPC_SyncSkeleton", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly FieldInfo CharacterDataIsSkeletonField = AccessTools.Field(typeof(CharacterData), "_isSkeleton");

		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 MethodInfo RopeAnchorProjectileGetShotMethod = AccessTools.Method(typeof(RopeAnchorProjectile), "GetShot", new Type[4]
		{
			typeof(Vector3),
			typeof(float),
			typeof(float),
			typeof(Vector3)
		}, (Type[])null);

		private static readonly Type AirportCheckInKioskType = AccessTools.TypeByName("AirportCheckInKiosk");

		private static readonly MethodInfo AirportCheckInKioskBeginIslandLoadRpcMethod = ((AirportCheckInKioskType != null) ? AccessTools.Method(AirportCheckInKioskType, "BeginIslandLoadRPC", new Type[2]
		{
			typeof(string),
			typeof(int)
		}, (Type[])null) : null);

		private static readonly Type MapGeneratorType = AccessTools.TypeByName("MapGenerator");

		private static readonly MethodInfo MapGeneratorGenerateAllMethod = ((MapGeneratorType != null) ? AccessTools.Method(MapGeneratorType, "GenerateAll", (Type[])null, (Type[])null) : null);

		private static readonly MethodInfo MapGeneratorClearAllMethod = ((MapGeneratorType != null) ? AccessTools.Method(MapGeneratorType, "ClearAll", (Type[])null, (Type[])null) : null);

		private static readonly FieldInfo MapGeneratorSeedField = ((MapGeneratorType != null) ? AccessTools.Field(MapGeneratorType, "seed") : null);

		private static readonly FieldInfo LoadingScreenHandlerLoadingField = GetFieldOrNull(typeof(LoadingScreenHandler), "loading");

		private static readonly PropertyInfo LoadingScreenHandlerLoadingProperty = GetPropertyOrNull(typeof(LoadingScreenHandler), "loading");

		private static readonly Dictionary<int, float> RopeVisualizerCorrectionUntilRealtime = new Dictionary<int, float>();

		private static readonly FieldInfo RopeAnchorProjectileLastShotToField = AccessTools.Field(typeof(RopeAnchorProjectile), "lastShotTo");

		private static readonly FieldInfo RopeAnchorProjectileLastShotTravelTimeField = AccessTools.Field(typeof(RopeAnchorProjectile), "lastShotTravelTime");

		private static readonly FieldInfo RopeAnchorProjectileLastShotRopeLengthField = AccessTools.Field(typeof(RopeAnchorProjectile), "lastShotRopeLength");

		private static readonly FieldInfo RopeAnchorProjectileLastShotFlyingRotationField = AccessTools.Field(typeof(RopeAnchorProjectile), "lastShotFlyingRotation");

		private static readonly FieldInfo RopeAttachedToAnchorField = AccessTools.Field(typeof(Rope), "attachedToAnchor");

		private static readonly FieldInfo RopeSpoolField = AccessTools.Field(typeof(Rope), "spool");

		private static readonly MethodInfo RopeAttachToAnchorRpcMethod = AccessTools.Method(typeof(Rope), "AttachToAnchor_Rpc", new Type[2]
		{
			typeof(PhotonView),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo RopeAttachToSpoolRpcMethod = AccessTools.Method(typeof(Rope), "AttachToSpool_Rpc", new Type[1] { typeof(PhotonView) }, (Type[])null);

		private static readonly MethodInfo RopeGetLengthInMetersMethod = AccessTools.Method(typeof(Rope), "GetLengthInMeters", (Type[])null, (Type[])null);

		private static readonly MethodInfo RopeSegmentTieMethod = AccessTools.Method(typeof(RopeSegment), "Tie", new Type[1] { typeof(Vector3) }, (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 MethodInfo MagicBeanVineFixedUpdateMethod = AccessTools.Method(typeof(MagicBeanVine), "FixedUpdate", (Type[])null, (Type[])null);

		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 FieldInfo CharacterItemsMaxSlotField = AccessTools.Field(typeof(CharacterItems), "MAX_SLOT");

		private static readonly FieldInfo PlayerLocalPlayerField = AccessTools.Field(typeof(Player), "localPlayer");

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

		private static readonly MethodInfo CharacterItemsEquipItemMethod = AccessTools.Method(typeof(CharacterItems), "Equip", new Type[1] { typeof(Item) }, (Type[])null);

		private static readonly MethodInfo CharacterItemsDropItemFromSlotRpcMethod = AccessTools.Method(typeof(CharacterItems), "DropItemFromSlotRPC", new Type[2]
		{
			typeof(byte),
			typeof(Vector3)
		}, (Type[])null);

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

		private static readonly PropertyInfo PhotonViewInstantiationIdProperty = GetPropertyOrNull(typeof(PhotonView), "InstantiationId");

		private static readonly PropertyInfo PhotonViewIsSceneViewProperty = GetPropertyOrNull(typeof(PhotonView), "IsSceneView");

		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 HashSet<STATUSTYPE> SkippedSavedStatuses = new HashSet<STATUSTYPE> { (STATUSTYPE)7 };

		private static readonly HashSet<DataEntryKey> ExplicitItemDataKeys = new HashSet<DataEntryKey>
		{
			(DataEntryKey)2,
			(DataEntryKey)12,
			(DataEntryKey)11,
			(DataEntryKey)8,
			(DataEntryKey)10,
			(DataEntryKey)1,
			(DataEntryKey)3,
			(DataEntryKey)13,
			(DataEntryKey)5,
			(DataEntryKey)7
		};

		private static SaveManagerPlugin Instance;

		private static int? PendingSeedForLoad;

		private static float PendingSeedSetRealtime;

		private static bool PendingSeedConsumedForLoad;

		private static bool PendingSeedStagedForLoad;

		private static int? ForcedDailyLevelIndexForLoad;

		private static bool ForcedDailyLevelIndexLogEmitted;

		private Harmony harmony;

		private ConfigEntry<bool> autoSaveEnabled;

		private ConfigEntry<float> autoSaveIntervalSeconds;

		private ConfigEntry<bool> verboseLogging;

		private string saveDirectory;

		private bool showUi;

		private bool isLoading;

		private float loadStartedRealtime = -1f;

		private bool ropeLinkRestoreSettledForCurrentLoad;

		private float lastRopeLinkRestoreRealtime = -1f;

		private int lastRopeLinkExpectedCount = -1;

		private int lastRopeLinkResolvedCount = -1;

		private Coroutine lateWorldReconcileCoroutine;

		private Coroutine deferredGroundRestoreCoroutine;

		private int lateWorldReconcileToken;

		private string lastGroundRestorePhase = string.Empty;

		private bool lastGroundRestoreMatchedAllForCurrentPhase;

		private bool lastGroundRestoreHadFailuresForCurrentPhase;

		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 readonly Dictionary<int, int> overflowTempEquipGenerationByPlayer = new Dictionary<int, int>();

		private readonly List<ProtectedGroundItemMarker> protectedGroundItemMarkers = new List<ProtectedGroundItemMarker>();

		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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00c8: 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");
			verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose Logging", true, "Enable detailed save/load diagnostics.");
			saveDirectory = Path.Combine(Paths.GameRootPath, "PeakSaves");
			if (!Directory.Exists(saveDirectory))
			{
				Directory.CreateDirectory(saveDirectory);
			}
			harmony = new Harmony("com.lucasandersen.peakallyouneedsavemanager");
			harmony.PatchAll();
			InstallRuntimeCompatibilityPatches();
			RefreshSaveFileList();
			SetStatus("Save manager ready.", Color.cyan, 2f);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded The All You Need Save Manager 1.0.1 by Lucas Andersen");
			LogVerbose("Verbose logging enabled. SaveDir='" + saveDirectory + "'");
		}

		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}");
			}
			overflowTempEquipGenerationByPlayer.Clear();
			protectedGroundItemMarkers.Clear();
			DestroyUiResources();
		}

		private void InstallRuntimeCompatibilityPatches()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			try
			{
				if (MapGeneratorGenerateAllMethod == null)
				{
					LogVerbose("MapGenerator.GenerateAll not found; skipping runtime seed compatibility patch.");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(SaveManagerPlugin), "MapGeneratorGenerateAllPrefix", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"MapGenerator compatibility prefix method could not be resolved.");
					return;
				}
				harmony.Patch((MethodBase)MapGeneratorGenerateAllMethod, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				LogVerbose("Applied runtime seed compatibility patch to MapGenerator.GenerateAll.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to apply MapGenerator runtime compatibility patch: " + ex.Message));
			}
		}

		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)
		{
			GUILayout.BeginVertical(entry.isCompatible ? cardStyle : cardWarningStyle, 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;
			if (GUILayout.Button("Overwrite", softButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(24f),
				GUILayout.Width(100f)
			}))
			{
				if (!CanSaveNow(showReason: true))
				{
					GUI.enabled = true;
					GUILayout.EndHorizontal();
					GUILayout.EndVertical();
					return;
				}
				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))
			{
				LogVerbose("StartLoadFromUi ignored due to empty path.");
				return;
			}
			LogVerbose("StartLoadFromUi path='" + fullPath + "'");
			showUi = false;
			ClearPendingConfirmation();
			pauseMenuPage?.PrepareForLoad();
			ClosePauseMenuForLoad();
			((MonoBehaviour)this).StartCoroutine(LoadSaveRoutine(fullPath));
		}

		private void ClosePauseMenuForLoad()
		{
			try
			{
				if ((Object)(object)EventSystem.current != (Objec